国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

學會這7種SQL進階用法,讓你少走99%的彎路!

這篇具有很好參考價值的文章主要介紹了學會這7種SQL進階用法,讓你少走99%的彎路!。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

引言

在日常業(yè)務開發(fā)中,熟練掌握SQL語言是至關重要的。除了基礎的增刪改查操作外,了解和掌握一些進階的SQL用法能夠讓你更高效地處理各種復雜的數(shù)據(jù)操作。本文將介紹幾種SQL進階用法,讓你少走99%的彎路,提高數(shù)據(jù)處理效率。

自定義排序

MySQL中,你可以通過使用自定義排序來指定特定字段的排序順序。通常情況下,MySQL的排序是按照默認的升序(ASC)或降序(DESC)進行的。但是,有時候你可能需要按照特定的順序進行排序,而不僅僅是升序或降序。這時就可以使用自定義排序。

下面我們來通過一個示例來講解自定義排序。

假設你有一個students表,其中包含學生的姓名和成績?,F(xiàn)在,你想按照自定義的順序?qū)W生進行排序,而不是按照成績的大小。例如,你想按照"A"、"B"、"C"、"D"、"E"這樣的順序進行排序。

MySql8.0以前我們需要使用ORDER BY結(jié)合CASE語句來自定義一個排序規(guī)則去實現(xiàn)。例如:

SELECT * 
FROM students 
ORDER BY 
  CASE 
    WHEN grade = 'A' THEN 1 
    WHEN grade = 'B' THEN 2 
    WHEN grade = 'C' THEN 3 
    WHEN grade = 'D' THEN 4 
    WHEN grade = 'E' THEN 5 
    ELSE 6 -- 處理其他情況,例如如果有其他成績值
  END;

執(zhí)行結(jié)果如下:

而在MySql8.0之后可以直接使用自定義排序規(guī)則通過FIELD()函數(shù)來實現(xiàn)自定義排序。FIELD()函數(shù)接受一個字段和一個值列表作為參數(shù),并返回該字段在值列表中的位置。上述示例我們可以改造為:

SELECT * 
FROM students 
ORDER BY  FIELD(grade,'A','B','C','D','E');

再例如我們在按照自定義的名稱的規(guī)則排序:

SELECT *
FROM students 
ORDER BY  FIELD(name, 'Eve','David','Charlie','Bob','Alice');

執(zhí)行結(jié)果:


需要注意的是,FIELD()函數(shù)會返回字段在值列表中的位置,如果字段的值不在值列表中,則返回0。所以如果你的字段可能包含不在值列表中的值,可能需要在排序時進行適當?shù)奶幚怼?/p>

這種方法相對簡單,并且在某些情況下非常方便,但也有一些限制。特別是,當值列表很長時,這種方法可能不夠靈活,因為需要在ORDER BY子句中硬編碼所有的值。

空值NULL排序

MySQL中,當涉及到NULL值排序時,通常,NULL值在升序排序(ASC)中被視為小于任何非NULL值,而在降序排序(DESC)中則被視為大于任何非NULL值。

SELECT * FROM students ORDER BY age ASC;

執(zhí)行結(jié)果:

SELECT * FROM students ORDER BY age DESC;

執(zhí)行結(jié)果:

如果你希望NULL值出現(xiàn)在排序結(jié)果的末尾或開頭,可以使用COALESCEIFNULL函數(shù)或者ORDER BY IF(ISNULL(字段), 0, 1)來替換NULL值,從而顯式控制其排序位置:

  1. 升序時將NULL值放在最后面:
SELECT * FROM students ORDER BY COALESCE(age, 999999) ASC;

或者

SELECT * FROM students ORDER BY IFNULL(age, 999999) ASC;

或者

SELECT * FROM students ORDER BY IF(ISNULL(age), 1, 0), age ASC;

執(zhí)行結(jié)果如下:

  1. 降序時把NULL值放在最前面:
SELECT * FROM students ORDER BY COALESCE(age, 999999) DESC;

或者

SELECT * FROM students ORDER BY IFNULL(age, 999999) DESC;

或者

SELECT * FROM students ORDER BY IF(ISNULL(age), 0, 1), age DESC;

執(zhí)行結(jié)果如下:

假如對需要排序的列的最大最小的邊界值可以確定,即邏輯上不會出現(xiàn)這么大的值的時候上述三種方式都可以實現(xiàn),否則建議使用ORDER BY IF(ISNULL(age), 0, 1)的方式,當然也建議不管那種情況都要使用這種方式。

CASE表達式

CASE表達式是一種條件表達式,類似于其他編程語言中的switch語句。它允許根據(jù)條件的不同返回不同的值。

CASE表達式的基本語法如下:

CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ...
    ELSE resultN
END
  • condition1、condition2等是條件,可以是任何邏輯表達式。
  • result1、result2等是對應條件為真時要返回的結(jié)果。
  • ELSE子句是可選的,用于處理所有條件都不滿足的情況,如果省略了ELSE子句且所有條件都不滿足,則返回NULL。
SELECT 
    name,
    score,
    CASE
        WHEN score >= 90 THEN 'A'
        WHEN score >= 80 THEN 'B'
        WHEN score >= 70 THEN 'C'
        ELSE 'D'
    END AS grade_level
FROM
    students;

執(zhí)行結(jié)果如下:

CASE表達式在SQL查詢中用途廣泛,可用于SELECT、UPDATESET等語句中,實現(xiàn)動態(tài)計算列值、根據(jù)條件更新值等功能。

分組連接函數(shù):GROUP_CONCAT

GROUP_CONCAT函數(shù)用于將每個組內(nèi)的行連接成一個字符串,并返回該字符串。通常在對結(jié)果集進行分組后,需要將每個分組內(nèi)的多個值合并成一個字符串時使用。該函數(shù)在MySQL中非常有用,特別是在處理與分組相關的數(shù)據(jù)時。

GROUP_CONCAT函數(shù)的語法:

GROUP_CONCAT([DISTINCT] expr [,expr ...]
             [ORDER BY {unsigned_integer | col_name | expr}
                 [ASC | DESC] [,col_name ...]]
             [SEPARATOR str_val])

  • DISTINCT:可選項,用于去除重復的值。
  • expr:要連接的表達式。
  • ORDER BY:可選項,用于指定連接后的字符串的排序方式。
  • SEPARATOR:可選項,用于指定連接后的字符串的分隔符,默認為逗號,。
SELECT
	class,
	GROUP_CONCAT( NAME ) AS students_list 
FROM
	students 
GROUP BY
	class;

查詢結(jié)果:

使用GROUP_CONCAT函數(shù)時,還可以通過ORDER BY子句可以指定連接后的字符串的排序方式。

SELECT
	class,
	GROUP_CONCAT( NAME ORDER BY age DESC SEPARATOR ';') AS students_list 
FROM
	students 
GROUP BY
	class;

執(zhí)行結(jié)果:

默認情況下GROUP_CONCAT函數(shù)的最大連接長度是1024個字符。如果你的連接超過了這個限制,可以使用SET SESSION group_concat_max_len = val;語句來調(diào)整最大連接長度。

分組統(tǒng)計數(shù)據(jù)后在進行統(tǒng)計匯總:WITH ROLLUP

WITH ROLLUP是MySQL中用于執(zhí)行聚合查詢并生成總計行(rollup summary)的選項之一。它允許在GROUP BY子句中創(chuàng)建一個額外的行,該行包含了對分組數(shù)據(jù)的匯總信息。這在需要同時查看詳細數(shù)據(jù)和總計數(shù)據(jù)時非常有用。

使用WITH ROLLUP時,查詢結(jié)果會包含每個分組的詳細數(shù)據(jù),以及一個總計行,該總計行匯總了所有分組的數(shù)據(jù)。

SELECT
	class,
	AVG( age ) 
FROM
	students 
WHERE
	age IS NOT NULL 
GROUP BY
	class WITH ROLLUP;

查詢結(jié)果:

結(jié)果中包含了每個年級的平均年齡,并且返回所有的班級的學生平均年齡。

需要注意的是,總計行中分組鍵列的值為NULL,表示匯總了所有分組的數(shù)據(jù)。這使得我們可以通過檢查分組鍵列是否為NULL來確定行是否為總計行。

子查詢提?。篧ITH AS

在MySQL中,WITH AS子句(也稱為子查詢提取函數(shù))允許你在一個查詢中創(chuàng)建一個臨時的命名子查詢(也稱為公共表表達式),然后在該查詢的后續(xù)部分引用這個子查詢。這有助于提高查詢的可讀性和簡潔性,尤其是當查詢中需要多次引用相同的子查詢時。

WITH AS子句的基本語法:

WITH cte_name AS (
    SELECT columns
    FROM table
    WHERE conditions
)
SELECT columns
FROM cte_name
WHERE conditions;

假如我們查詢分數(shù)大于80的,并且評級為A的并且不是2班的學生信息:

WITH s1 AS ( SELECT * FROM students WHERE score > 80 ),
s2 AS ( SELECT * FROM students WHERE class = 2 ) 
SELECT
	* 
FROM
	s1 
WHERE
	s1.id NOT IN ( SELECT s2.id FROM s2 ) 
	AND s1.grade = 'A';

結(jié)果如下:

WITH AS是從MySql 8.0.1開始提供

優(yōu)雅處理數(shù)據(jù)插入、更新時主鍵或者唯一鍵沖突

在日常開發(fā)中,我們嘗嘗在插入數(shù)據(jù)時會遇到唯一鍵沖突導致插入失敗的問題。如下:

假如我們的唯一鍵為:

ALTER TABLE students ADD UNIQUE KEY `uk_class_name` (`name`,`class`) USING BTREE;

我們執(zhí)行以下sql:

SELECT * FROM students WHERE class = 1 and name = 'Alice';

查詢結(jié)果:

此時我們在插入一條數(shù)據(jù):

INSERT INTO students (name, grade, age, score, class) VALUES ('Alice', 'A', 18, 98, 1);

發(fā)現(xiàn)報錯:

我們通常的做法時先按照唯一鍵查詢一遍數(shù)據(jù),如果存在則先刪除數(shù)據(jù),在進行插入。這種做法略顯麻煩,并且可能會誤刪數(shù)據(jù)。此時我們就可以采取以下三種方法區(qū)優(yōu)雅處理。

IGNORE

IGNORE關鍵字用于在執(zhí)行插入、更新或刪除操作時,忽略特定類型的錯誤,而不是中止整個操作。特別是在插入或更新數(shù)據(jù)時,如果存在唯一索引沖突或主鍵沖突,使用IGNORE關鍵字可以使得操作繼續(xù)進行而不是因為錯誤而中斷。

語法如下:

INSERT IGNORE INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);

UPDATE IGNORE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;

上述插入語句的示例中,我們使用IGNORE關鍵字:

INSERT IGNORE INTO students (name, grade, age, score, class) VALUES ('Alice', 'A', 18, 98, 1);

執(zhí)行成功。

查詢數(shù)據(jù)發(fā)現(xiàn),數(shù)據(jù)沒有變化:

如果UPDATE使用了IGNORE關鍵字,在更新數(shù)據(jù)時忽略那些會導致錯誤的行,比如更新更新后會違反唯一約束。

UPDATE IGNORE students SET name = 'Alice' WHERE id = 3;

此時會執(zhí)行成功:

IGNORE在使用時應該謹慎,它可能會掩蓋潛在的業(yè)務邏輯錯誤或數(shù)據(jù)一致性問題。并且在事務安全性和完整性要求較高的場景下可能并不適用。

REPLACE

REPLACE INTO是MySQL中用于向表中插入或替換數(shù)據(jù)的一種特殊語法。它類似于INSERT INTO語句,但是在插入數(shù)據(jù)時,如果發(fā)現(xiàn)表中已存在具有相同唯一索引或主鍵的記錄,則會刪除現(xiàn)有記錄,然后插入新記錄,而不是拋出錯誤或?qū)е虏迦氩僮魇?。即有則刪除在插入,沒有則插入。

語法如下:

REPLACE INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);

你也可以使用REPLACE INTOSELECT語句結(jié)合使用來替換表中的數(shù)據(jù):

REPLACE INTO table_name (column1, column2, ...)
SELECT column1, column2, ...
FROM another_table
WHERE condition;

我們執(zhí)行如下sql:

REPLACE INTO students (name, grade, age, score, class) VALUES ('Alice', 'A', 18, 98, 1);

執(zhí)行成功,查詢這條記錄:

此時我們發(fā)現(xiàn)記錄的id重新生成了,并且數(shù)據(jù)頁是插入的最新的數(shù)據(jù)。

REPLACE INTO會首先嘗試刪除表中具有相同唯一索引或主鍵的記錄,然后再插入新記錄。因此,在使用REPLACE INTO時應當謹慎,以確保不會意外刪除需要保留的數(shù)據(jù)。

ON DUPLICATE KEY UPDATE

在MySQL中,ON DUPLICATE KEY UPDATE是用于在執(zhí)行INSERT語句時,如果發(fā)生唯一鍵沖突(即違反了唯一索引或主鍵約束),則執(zhí)行后面的更新操作。

當你想要向表中插入一行數(shù)據(jù),但是如果這一行數(shù)據(jù)已經(jīng)存在(即主鍵或唯一索引已經(jīng)存在),則更新該行數(shù)據(jù)而不是插入新的行,即有則更新,沒有則插入。

語法如下:

INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...)
ON DUPLICATE KEY UPDATE column1 = value1, column2 = value2, ...;

我們執(zhí)行以下sql:

INSERT IGNORE INTO students ( NAME, grade, age, score, class )
VALUES
	( 'Alice', 'A', 18, 98, 1 ) 
	ON DUPLICATE KEY UPDATE score = 100,
	grade = 'B';

執(zhí)行成功,重新看一下這條數(shù)據(jù):

數(shù)據(jù)已執(zhí)行了更新操作。

這種方式適用于需要維護唯一記錄(如用戶名、郵箱等)的情況下,無需預先檢查是否存在重復,就能保證數(shù)據(jù)的一致性和完整性。同時,它也減少了對數(shù)據(jù)庫的請求次數(shù),提高了處理效率。

總結(jié)

掌握以上這幾種SQL進階用法,能夠讓你在日常的數(shù)據(jù)處理工作中更加得心應手,少走很多彎路。通過優(yōu)化查詢邏輯、處理異常情況以及執(zhí)行插入或更新操作,你可以更高效地管理和操作數(shù)據(jù)庫,提升工作效率,從而更好地應對各種復雜的數(shù)據(jù)處理需求。

本文已收錄于我的個人博客:碼農(nóng)Academy的博客,專注分享Java技術干貨,包括Java基礎、Spring Boot、Spring Cloud、Mysql、Redis、Elasticsearch、中間件、架構(gòu)設計、面試題、程序員攻略等文章來源地址http://www.zghlxwxcb.cn/news/detail-837794.html

到了這里,關于學會這7種SQL進階用法,讓你少走99%的彎路!的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 3分鐘讓你學會axios在vue項目中的基本用法(建議收藏)

    3分鐘讓你學會axios在vue項目中的基本用法(建議收藏)

    目錄 Axios Axios簡介 一、axios是干啥的 二、安裝使用 三、Axios請求方式 1、axios可以請求的方法: 2、get請求 3、post請求 4、put和patch請求 5、delete請求 6、并發(fā)請求 四、Axios實例 1、創(chuàng)建axios實例 2、axios全局配置 3、axios實例配置 4、axios請求配置 五、攔截器 1、請求攔截器 2、響應

    2024年01月20日
    瀏覽(71)
  • 【Mysql】一篇學會SQL中的遞歸的用法

    【Mysql】一篇學會SQL中的遞歸的用法

    ?????????SQL遞歸查詢是一種用于處理具有層次結(jié)構(gòu)的數(shù)據(jù)的技術。它使用遞歸函數(shù)來遍歷樹形結(jié)構(gòu),例如組織結(jié)構(gòu)、分類結(jié)構(gòu)等等。 ????????遞歸查詢通常使用 \\\"?WITH RECURSIVE \\\"? 語句實現(xiàn)。 ????????WITH RECURSIVE 語句包含兩部分: ? ? ? ? ? ? a.遞歸部分: 定義了如

    2024年02月13日
    瀏覽(26)
  • MyBatis進階:掌握MyBatis動態(tài)SQL與模糊查詢、結(jié)果映射,讓你在面試中脫穎而出??!

    MyBatis進階:掌握MyBatis動態(tài)SQL與模糊查詢、結(jié)果映射,讓你在面試中脫穎而出??!

    目錄 一、引言 二、MyBatis動態(tài)SQL 2.1.if元素使用 2.2.foreach元素使用 三、MyBatis模糊查詢 ①使用#{字段名} ②使用${字段名} ③使用concat{\\\'%\\\',#{字段名},\\\'%\\\'} 總結(jié) 四、MyBatis結(jié)果映射 4.1.案例演示 4.1.1.resultType進行結(jié)果映射 4.1.2.resultMap進行結(jié)果映射 在當今的軟件開發(fā)環(huán)境中,數(shù)據(jù)庫的使

    2024年02月11日
    瀏覽(21)
  • 干貨分享:AI繪圖學習心得-Midjourney繪畫AI,讓你的AI繪畫之路少走彎路

    干貨分享:AI繪圖學習心得-Midjourney繪畫AI,讓你的AI繪畫之路少走彎路

    本篇沒有什么長篇大論,全部都是實用心得總結(jié)。接下來,我們將分享關于Midjourney繪畫AI的實用心得總結(jié),包括構(gòu)圖指令結(jié)構(gòu)、常用指令、操作技巧、常用風格詞匯和構(gòu)圖詞匯。 如果你想入門MidJourney可以查看這篇教程:Midjourney最全操作指南,從入門到精通 AI繪畫的核心就是

    2024年02月11日
    瀏覽(30)
  • [C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。

    [C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。

    W...Y的主頁 ??? 代碼倉庫分享??? ? ??前言:? 在C++的世界里,模板是一種強大而神奇的工具,宛如編程的瑰寶匣,蘊藏著無限的可能性。它們不僅能夠讓我們編寫通用的代碼,還能夠在編譯時實現(xiàn)類型安全的抽象。然而,模板的奧秘并非易見,它們像是編碼世界中的魔法

    2024年02月04日
    瀏覽(18)
  • 功能測試進階自動化測試如何摸清學習方向,少走彎路呢?

    目錄 拋開疑問,只做學術探討 小白在想什么? 蓋樓之前先打好地基,首先需要學習一門語言 語言入門后,正式踏上開始自動化成神之路,入門篇Selenium 玩膩了Selenium 開始接觸自動化框架unittest/testNG 不滿足于單元測試框架的功能 學習自動化框架 初始接口測試 嘗試學習Requ

    2024年02月13日
    瀏覽(20)
  • 讓你立刻學會指針

    讓你立刻學會指針

    ??個人主頁:fighting小澤 ??作者簡介:目前正在學習C語言和數(shù)據(jù)結(jié)構(gòu) ??博客專欄:C語言學習 ???歡迎關注:評論????點贊????留言???? 指針是什么? 指針理解的2個要點: 指針是內(nèi)存中一個最小單元的編號,也就是地址 平時口語中說的指針,通常指的是指針變量

    2023年04月21日
    瀏覽(19)
  • ssh詳解–讓你徹底學會ssh

    ssh詳解–讓你徹底學會ssh

    SSH全稱secure shell,安全外殼協(xié)議(安全的shell),是一個計算機網(wǎng)絡協(xié)議(默認端口號為22)。通過ssh協(xié)議可以在客戶端 安全 (提供身份認證、信息加密)的 遠程連接 LInux服務器或其他設備。 使用廣泛的Xshell軟件就是基于SSH協(xié)議遠程連接。 SSH遠程連接之后能干什么? SSH遠程

    2024年02月05日
    瀏覽(17)
  • 學會 CompletableFuture:讓你的代碼免受阻塞之苦!

    學會 CompletableFuture:讓你的代碼免受阻塞之苦!

    來源:https://juejin.cn/post/6844904024332828685 通過閱讀本篇文章你將了解到: CompletableFuture的使用 CompletableFure異步和同步的性能測試 已經(jīng)有了Future為什么仍需要在JDK1.8中引入CompletableFuture CompletableFuture的應用場景 對CompletableFuture的使用優(yōu)化 查詢所有商店某個商品的價格并返回,并

    2024年02月08日
    瀏覽(27)
  • 視頻內(nèi)容轉(zhuǎn)文字怎么轉(zhuǎn),讓你學會3個簡單方法

    視頻內(nèi)容轉(zhuǎn)文字怎么轉(zhuǎn),讓你學會3個簡單方法

    隨著視頻內(nèi)容的普及,視頻中包含的文字信息也變得越來越重要。為了更好地獲取視頻中的文字信息,將視頻內(nèi)容轉(zhuǎn)換成文字成為一種必要的操作。今天和大家分享視頻內(nèi)容轉(zhuǎn)文字怎么轉(zhuǎn),手把手教你3個方法,快學起來吧。 方法一:使用工具轉(zhuǎn)換 “視頻轉(zhuǎn)文字助手”是一款

    2024年02月07日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包