分享10個高級sql寫法

来源:https://www.cnblogs.com/wayn111/archive/2023/03/12/17209808.html
-Advertisement-
Play Games

本文主要介紹博主在以往開發過程中,對於不同業務所對應的 sql 寫法進行歸納總結而來。進而分享給大家。 本文所講述 sql 語法都是基於 MySql 8.0 博主github地址:http://github.com/wayn111 歡迎大家關註,點個star 一、ORDER BY FIELD() 自 ...


本文主要介紹博主在以往開發過程中,對於不同業務所對應的 sql 寫法進行歸納總結而來。進而分享給大家。

  • 本文所講述 sql 語法都是基於 MySql 8.0
  • 博主github地址:http://github.com/wayn111  歡迎大家關註,點個star

一、ORDER BY FIELD() 自定義排序邏輯

MySql 中的排序 ORDER BY 除了可以用 ASC 和 DESC,還可以通過ORDER BY FIELD(str,str1,...)自定義字元串/數字來實現排序。這裡用 order_diy 表舉例,結構以及表數據展示:

image.png
ORDER BY FIELD(str,str1,...) 自定義排序sql如下:

SELECT * from order_diy ORDER BY FIELD(title,'九陰真經', 
'降龍十八掌','九陰白骨爪','雙手互博','桃花島主',
'全真內功心法','蛤蟆功','銷魂掌','靈白山少主');

查詢結果如下:

image.png
如上,我們設置自定義排序欄位為 title 欄位,然後將我們自定義的排序結果跟在 title 後面。

二、CASE 表達式

case when then else end表達式功能非常強大可以幫助我們解決 if elseif else 這種問題,這裡繼續用 order_diy 表舉例,假如我們想在 order_diy 表加一列 level 列,根據money 判斷大於60就是高級,大於30就是中級,其餘顯示低級,sql 如下:

SELECT *, 
case when money > 60 then '高級' 
when money > 30 then '中級' 
else '低級' END level 
from order_diy;

查詢結果:

image.png

三、EXISTS 用法

我猜大家在日常開發中,應該都對關鍵詞 exists 用的比較少,估計使用 in 查詢偏多。這裡給大家介紹一下 exists 用法,引用官網文檔:

image.png
可知 exists 後面是跟著一個子查詢語句,它的作用是根據主查詢的數據,每一行都放到子查詢中做條件驗證,根據驗證結果(TRUE 或者 FALSE),TRUE的話該行數據就會保留,下麵用 emp 表和 dept 表進行舉例,表結構以及數據展示:

image.png
計入我們現在想找到 emp 表中 dept_name 與 dept表 中 dept_name 對應不上員工數據,sql 如下:

SELECT * from emp e where exists (
SELECT * from dept p where e.dept_id = p.dept_id 
and e.dept_name != p.dept_name
)

查詢結果:

image.png
我們通過 exists 語法將外層 emp 表全部數據 放到子查詢中與一一與 dept 表全部數據進行比較,只要有一行記錄返回true。畫個圖展示主查詢所有記錄與子查詢交互如下:

image.png

  • 第一條記錄與子查詢比較時,全部返回 false,所以第一行不展示。
  • 第二行記錄與子查詢比較時,發現 銷售部門 與 dept 表第二行 銷售部 對應不上,返回 true,所以主查詢該行記錄會返回。
  • 第二行以後記錄執行結果同第一條。

四、GROUP_CONCAT(expr) 組連接函數

GROUP_CONCAT(expr) 組連接函數可以返回分組後指定欄位的字元串連接形式,並且可以指定排序邏輯,以及連接字元串,預設為英文逗號連接。這裡繼續用 order_diy 表舉例:sql 如下:

SELECT name, GROUP_CONCAT(title ORDER BY id desc  SEPARATOR '-') 
from order_diy GROUP BY name ORDER BY NULL;

查詢結果:

image.png

如上我們通過 GROUP_CONCAT(title ORDER BY id desc SEPARATOR '-') 語句,指定分組連接 title 欄位並按照 id 排序,設置連接字元串為 -

五、自連接查詢

自連接查詢是 sql 語法里常用的一種寫法,掌握了自連接的用法我們可以在 sql 層面輕鬆解決很多問題。這裡用 tree 表舉例,結構以及表數據展示:

image.png
tree 表中通過 pid 欄位與 id 欄位進行父子關聯,假如現在有一個需求,我們想按照父子層級將 tree 表數據轉換成 一級職位 二級職位 三級職位 三個列名進行展示,sql 如下:

SELECT t1.job_name '一級職位', t2.job_name '二級職位', t3.job_name '三級職位' 
from tree t1 join tree t2 on t1.id = t2.pid left join tree t3 on t2.id = t3.pid 
where t1.pid = 0;

結果如下:

image.png
我們通過 tree t1 join tree t2 on t1.id = t2.pid 自連接展示 一級職位 二級職位,再用 left join tree t3 on t2.id = t3.pid 自連接展示 二級職位 三級職位,最後通過where 條件 t1.pid = 0過濾掉非一級職位的展示,完成這個需求。

六、更新 emp 表和 dept 表關聯數據

這裡繼續使用上文提到的 emp 表和 dept 表,數據如下:
image.png
可以看到上述 emp 表中 jack 的部門名稱與 dept 表實際不符合,現在我們想將 jack 的部門名稱更新成 dept 表的正確數據,sql 如下:

update emp, dept set emp.dept_name = dept.dept_name
where emp.dept_id = dept.dept_id;

查詢結果:
image.png

我們可以直接關聯 emp 表和 dept 表並設置關聯條件,然後更新 emp 表的 dept_name 為 dept 表的 dept_name。

七、ORDER BY 空值 NULL 排序

ORDER BY 字句中可以跟我們要排序的欄位名稱,但是當欄位中存在 null 值時,會對我們的排序結果造成影響。我們可以通過 ORDER BY IF(ISNULL(title), 1, 0) 語法將 null 值轉換成0或1,來達到將 null 值放到前面還是後面進行排序的效果。

SELECT * FROM test_rollup ORDER BY  IF(ISNULL(title), 0, 1), money;

查詢結果:

image.png

八、with rollup 分組統計數據的基礎上再進行統計彙總

MySql 中可以使用 with rollup 在分組統計數據的基礎上再進行統計彙總,即用來得到 group by 的彙總信息。這裡繼續用order_diy 表舉例,sql 如下:

SELECT name, SUM(money) as money 
FROM order_diy GROUP BY name WITH ROLLUP;

查詢結果:

image.png
可以看到通過 GROUP BY name WITH ROLLUP 語句,查詢結果最後一列顯示了分組統計的彙總結果。但是 name 欄位最後顯示為 null,我們可以通過 coalesce() 比較函數,返回第一個非空參數。

SELECT coalesce(name, '總金額') name, SUM(money) as money 
FROM order_diy GROUP BY name WITH ROLLUP;

查詢結果:

image.png

九、with as 提取臨時表別名

with as 語法需要 MySql 8.0以上版本,它的作用主要是提取子查詢,方便後續共用,更多情況下會用在數據分析的場景上。

如果一整句查詢中多個子查詢都需要使用同一個子查詢的結果,那麼就可以用with as,將共用的子查詢提取出來,加個別名。後面查詢語句可以直接用,對於大量複雜的SQL語句起到了很好的優化作用。這裡繼續用 order_diy 表舉例,這裡使用with as給出sql 如下:

-- 使用 with as
with t1 as (SELECT * from order_diy where money > 30),
t2 as (SELECT * from order_diy where money > 60)
SELECT * from t1 
where t1.id not in (SELECT id from  t2) and t1.name = '周伯通';

查詢結果:

image.png
這個 sql 查詢了 order_diy 表中 money 大於30且小於等於60之間並且 name 是周伯通的記錄。

10、存在就更新,不存在就插入

MySql 中通過on duplicate key update語法來實現存在就更新,不存在就插入的邏輯。插入或者更新時,它會根據表中主鍵索引或者唯一索引進行判斷,如果主鍵索引或者唯一索引有衝突,就會執行on duplicate key update後面的賦值語句。
這裡通過 news 表舉例,表結構和說數據展示,其中 news_code 欄位有唯一索引:

image.png
添加sql:

-- 第一次執行添加語句
INSERT INTO `news` (`news_title`, `news_auth`, `news_code`) 
VALUES ('新聞3', '小花', 'wx-0003') 
on duplicate key update news_title = '新聞3';
-- 第二次執行修改語句
INSERT INTO `news` (`news_title`, `news_auth`, `news_code`) 
VALUES ('新聞4', '小花', 'wx-0003') 
on duplicate key update news_title = '新聞4';

結果如下:

image.png

總結

到這裡,本文所分享的10個高級sql寫法就全部介紹完了,希望對大家日常開發 sql 編寫有所幫助,喜歡的朋友們可以點贊加關註

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Blazor Server,即運行在伺服器上的 Blazor 應用程式,它的優點是應用程式在首次運行時,客戶端不需要下載運行時。但它的代碼是在伺服器上執行的,然後通過 SignalR 通信來更新客戶端的 UI,所以它要求必須建立 Web Socket 連接。 用於 Blazor 應用的 Signal ...
  • 上篇文章我們介紹了 VUE+.NET應用系統的國際化-整體設計思路 系統國際化改造整體設計思路如下: 提供一個工具,識別前後端代碼中的中文,形成多語言詞條,按語言、界面、模塊統一管理多有的多語言詞條 提供一個翻譯服務,批量翻譯多語言詞條 提供一個詞條服務,支持後端代碼在運行時根據用戶登錄的語言,動態 ...
  • 前言 之前寫過一篇基於ML.NET的手部關鍵點分類的博客,可以根據圖片進行手部的提取分類,於是我就將手勢分類和攝像頭數據結合,集成到了我開發的電子腦殼軟體里。 電子腦殼是一個為稚暉君開源的桌面機器人ElectronBot提供一些軟體功能的桌面程式項目。它是由綠蔭阿廣也就是我開發的,使用了微軟的WAS ...
  • 在 WebAssembly 中使用 Rust 編寫 eBPF 程式併發布 OCI 鏡像 作者:於桐,鄭昱笙 eBPF(extended Berkeley Packet Filter)是一種高性能的內核虛擬機,可以運行在內核空間中,以收集系統和網路信息。隨著電腦技術的不斷發展,eBPF 的功能日益強 ...
  • 一般來說,有時為了方便會直接在Ubuntu終端登陸root賬戶獲取許可權 在root下打開vscode會提示無法打開。 環境:Ubuntu22.04 解決辦法: 終端輸入: vi ~/.bashrc 添加一行: alias code='/usr/share/code/code . --no-sandb ...
  • apt-get update更新時出現錯誤,提示Release文件已經過期,無論是使用kali官方源還是阿裡源、中科大源都報該錯誤。 網上查找相關資料,簽名出錯需要下載數字簽名,方案如下: wget archive.kali.org/archive-key.asc //下載簽名 apt-key ad ...
  • 痞子衡嵌入式半月刊: 第 73 期 這裡分享嵌入式領域有用有趣的項目/工具以及一些熱點新聞,農曆年分二十四節氣,希望在每個交節之日準時發佈一期。 本期刊是開源項目(GitHub: JayHeng/pzh-mcu-bi-weekly),歡迎提交 issue,投稿或推薦你知道的嵌入式那些事兒。 上期回顧 ...
  • 經常用老毛桃裝系統,也裝過很多次Ubuntu+windows雙系統,但是對系統啟動的原理卻一直沒搞清楚。 這次就遇到了棘手的問題:裝完Ubuntu之後,開機的引導選項里沒有windows boot manager,直接就進了Ubuntu。 復盤一下安裝過程 (1)我是雙固態,一個裝了win10,另一 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...