最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL從零掌握?CRUD?核心操作大全:詳解增刪改查、聚合過(guò)濾與實(shí)戰(zhàn)避坑指南

 更新時(shí)間:2026年07月23日 10:37:21   作者:Cx330?  
CRUD(Create、Retrieve、Update、Delete)是數(shù)據(jù)庫(kù)操作的核心基石,涵蓋了數(shù)據(jù)的?增、刪、改、查?,本文介紹MySQL從零掌握CRUD核心操作大全:詳解增刪改查、聚合過(guò)濾與實(shí)戰(zhàn)避坑指南,感興趣的朋友一起看看吧

前言:

在軟件開(kāi)發(fā)的世界里,幾乎所有的業(yè)務(wù)邏輯都離不開(kāi)四個(gè)基本動(dòng)作:CRUD(Create 增加、Retrieve 讀取、Update 更新、Delete 刪除)。雖然這四個(gè)詞聽(tīng)起來(lái)很簡(jiǎn)單,但在實(shí)際的生產(chǎn)環(huán)境和面試考核中,MySQL 的細(xì)節(jié)表現(xiàn)常常讓人抓狂——例如:主鍵沖突時(shí)如何優(yōu)雅處理?WHERE 為什么不能用別名?DELETETRUNCATE 究竟有什么區(qū)別?為什么說(shuō) SQL 執(zhí)行順序是開(kāi)發(fā)者的必修課?

今天這篇萬(wàn)字長(zhǎng)文,將基于最經(jīng)典的場(chǎng)景(學(xué)生成績(jī)管理系統(tǒng)、經(jīng)典員工信息表),帶大家一行行拆解 MySQL 基礎(chǔ)查詢的方方面面。不管你是數(shù)據(jù)庫(kù)初學(xué)者,還是準(zhǔn)備面試的道友,建議收藏反復(fù)研讀!

一、 Create(創(chuàng)建 & 插入)

在進(jìn)行數(shù)據(jù)操作之前,我們首先需要有一張能夠承載數(shù)據(jù)的表。我們以創(chuàng)建一張最簡(jiǎn)單的 students 表為例:

CREATE TABLE students (
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    sn INT NOT NULL UNIQUE COMMENT '學(xué)號(hào)',
    name VARCHAR(20) NOT NULL,
    qq VARCHAR(20)
);

1.1 單行數(shù)據(jù)與全列插入

全列插入指的是我們不指定需要插入的列名,直接提供整行所有字段的值。

注意:如果不指定列名,那么你所提供的數(shù)據(jù)數(shù)量和順序,必須與創(chuàng)建表時(shí)的列定義完全一致!

-- 插入兩條完整的記錄
-- 即使 id 是自增主鍵,我們也可以明確指定它,MySQL 會(huì)直接采用我們指定的值
INSERT INTO students VALUES (100, 10000, '唐三藏', NULL);
INSERT INTO students VALUES (101, 10001, '孫悟空', '11111');

當(dāng)然,在實(shí)際開(kāi)發(fā)中,我們通常不需要每次都顯式手動(dòng)去寫(xiě)自增的id,此時(shí)需要明確指定我們要插入的列名:

INSERT INTO students (sn, name, qq) VALUES (10002, '沙悟凈', '22222');

1.2 多行數(shù)據(jù)與指定列插入

在實(shí)際的業(yè)務(wù)場(chǎng)景中,為了減少數(shù)據(jù)庫(kù)連接的建立與斷開(kāi)次數(shù),提高插入效率,我們應(yīng)當(dāng)極力避免用循環(huán)去一條條執(zhí)行 INSERT,而是采用批量插入

-- 批量指定列插入多行數(shù)據(jù)
INSERT INTO students (id, sn, name) VALUES
(102, 20001, '曹孟德'),
(103, 20002, '孫仲謀');

一次性插入多行可以極大地降低網(wǎng)絡(luò) I/O 成本,是寫(xiě)出高性能 SQL 的基本功。

1.3 插入否則更新(ON DUPLICATE KEY UPDATE)

當(dāng)我們向數(shù)據(jù)庫(kù)插入數(shù)據(jù)時(shí),常常會(huì)由于主鍵(Primary Key)或者唯一鍵(Unique Key)沖突導(dǎo)致插入失敗。例如:

-- 由于 id=100 已經(jīng)存在,主鍵沖突
INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大師');
-- 報(bào)錯(cuò):ERROR 1062 (23000): Duplicate entry '100' for key 'PRIMARY'
-- 由于 sn=20001 已經(jīng)存在,唯一鍵沖突
INSERT INTO students (sn, name) VALUES (20001, '曹阿瞞');
-- 報(bào)錯(cuò):ERROR 1062 (23000): Duplicate entry '20001' for key 'sn'

為了解決這種“存在則更新,不存在則插入”的業(yè)務(wù)需求,MySQL 提供了極其好用的:

INSERT ... ON DUPLICATE KEY UPDATE column = value [, column = value] ...

實(shí)戰(zhàn)演示

INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大師')
ON DUPLICATE KEY UPDATE sn = 10010, name = '唐大師';

?? 受影響行數(shù)(ROW_COUNT)的含義:

通過(guò) SELECT ROW_COUNT(); 可以查看剛才的操作對(duì)表產(chǎn)生了多少行實(shí)質(zhì)性的改動(dòng):

  • 0 行受影響:發(fā)現(xiàn)主鍵/唯一鍵沖突,但沖突行原本的數(shù)據(jù)和我們要更新的數(shù)據(jù)一模一樣,因此未作實(shí)質(zhì)性改動(dòng)。
  • 1 行受影響:未發(fā)現(xiàn)任何主鍵/唯一鍵沖突,直接作為全新數(shù)據(jù)插入成功。
  • 2 行受影響:發(fā)現(xiàn)主鍵/唯一鍵沖突,且新舊數(shù)據(jù)不同,MySQL 執(zhí)行了舊數(shù)據(jù)物理刪除并在原地更新的操作。

1.4 替換(REPLACE INTO)

除了上述的“插入否則更新”之外,MySQL 還有一種更為簡(jiǎn)單粗暴的方案:REPLACE INTO。

REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞞');
  • 工作機(jī)制:如果主鍵或唯一鍵沒(méi)有沖突,則直接執(zhí)行 INSERT。如果發(fā)生沖突,則先刪除(DELETE)該行沖突的數(shù)據(jù),然后再重新執(zhí)行插入(INSERT)。
  • 返回值:若無(wú)沖突,返回 1 row affected;若有沖突并發(fā)生替換,則返回 2 rows affected(刪除 1 行,插入 1 行)。

二、 Retrieve(讀取 & 查詢)

數(shù)據(jù)插進(jìn)去了,最核心的任務(wù)就是把它們高效率、多樣化地查詢出來(lái)。我們先搭建一個(gè)經(jīng)典的考試成績(jī)表 exam_result 來(lái)演示各種查詢玩法:

CREATE TABLE exam_result (
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL COMMENT '同學(xué)姓名',
    chinese FLOAT DEFAULT 0.0 COMMENT '語(yǔ)文成績(jī)',
    math FLOAT DEFAULT 0.0 COMMENT '數(shù)學(xué)成績(jī)',
    english FLOAT DEFAULT 0.0 COMMENT '英語(yǔ)成績(jī)'
);
-- 灌入測(cè)試數(shù)據(jù)
INSERT INTO exam_result (name, chinese, math, english) VALUES
('唐三藏', 67, 98, 56),
('孫悟空', 87, 78, 77),
('豬悟能', 88, 98, 90),
('曹孟德', 82, 84, 67),
('劉玄德', 55, 85, 45),
('孫權(quán)', 70, 73, 78),
('宋公明', 75, 65, 30);

2.1 SELECT 基本查詢

2.1.1 全列查詢

SELECT * FROM exam_result;

?? 博主警示(避坑點(diǎn)): 在實(shí)際生產(chǎn)環(huán)境中,極其不建議使用 SELECT *

  1. 查詢的列越多,代表著網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量越大,極易拉胯帶寬。
  2. 會(huì)導(dǎo)致 MySQL 優(yōu)化器無(wú)法進(jìn)行“覆蓋索引(Covering Index)”優(yōu)化,影響查詢性能。

2.1.2 指定列查詢

查詢需要的列即可,列的顯示順序可以根據(jù)業(yè)務(wù)需要任意調(diào)換:

SELECT id, name, english FROM exam_result;

2.1.3 查詢字段為表達(dá)式

MySQL 支持在 SELECT 子句中直接書(shū)寫(xiě)表達(dá)式。這些表達(dá)式甚至可以不需要包含字段:

SELECT id, name, 10 FROM exam_result; -- 會(huì)輸出一列全為10的數(shù)據(jù)
SELECT id, name, english + 10 FROM exam_result; -- 對(duì)英語(yǔ)成績(jī)進(jìn)行“物理加分”展示
SELECT id, name, chinese + math + english FROM exam_result; -- 計(jì)算總分

2.1.4 為查詢結(jié)果指定別名(AS)

上述的 chinese + math + english 作為一個(gè)列名顯得非常冗長(zhǎng),我們可以通過(guò) AS 關(guān)鍵字來(lái)指定簡(jiǎn)短好看的別名:

SELECT id, name, (chinese + math + english) AS 總分 FROM exam_result;
-- 提示:AS 關(guān)鍵字可省略
SELECT id, name, (chinese + math + english) 總分 FROM exam_result;

2.1.5 查詢結(jié)果去重(DISTINCT)

當(dāng)我們想了解全班數(shù)學(xué)成績(jī)都有哪些分?jǐn)?shù)時(shí)(不重復(fù)顯示),可以使用 DISTINCT

SELECT DISTINCT math FROM exam_result;

2.2 WHERE 條件過(guò)濾

在實(shí)際操作中,我們幾乎總是需要按照特定條件對(duì)記錄進(jìn)行篩選。在介紹具體案例前,我們需要熟記以下兩張經(jīng)典表:

比較運(yùn)算符

運(yùn)算符

說(shuō)明

>, >=, <, <=

大于、大于等于、小于、小于等于

=

等于(NULL不安全)。例如 NULL = NULL 的判斷結(jié)果為 NULL(在 SQL 里 NULL 代表未知,不能用 = 比較)

<=>

等于(NULL安全)。例如 NULL <=> NULL 的結(jié)果是 TRUE (1)

!=, <>

不等于

BETWEEN a0 AND a1

閉區(qū)間范圍匹配 [a0, a1]

IN (option1, option2...)

離散值匹配。只要值在括號(hào)選項(xiàng)內(nèi)即返回 TRUE

IS NULL

判斷是否為空

IS NOT NULL

判斷是否不為空

LIKE

模糊匹配。% 匹配任意多個(gè)字符;_ 嚴(yán)格匹配單個(gè)字符

邏輯運(yùn)算符

運(yùn)算符

說(shuō)明

AND

多個(gè)條件必須全部滿足

OR

多個(gè)條件只要滿足其中一個(gè)即可

NOT

否定后面的條件

2.2.1 基礎(chǔ)比較案例:查詢英語(yǔ)不及格(< 60)的同學(xué)

SELECT name, english FROM exam_result WHERE english < 60;

2.2.2 范圍查詢案例:查詢語(yǔ)文成績(jī)?cè)?[80, 90] 分之間的同學(xué)

方案一:使用 AND 邏輯連接

SELECT name, chinese FROM exam_result WHERE chinese >= 80 AND chinese <= 90;

方案二:使用 BETWEEN ... AND ...(包含邊界值)

SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;

2.2.3 離散匹配案例:查詢數(shù)學(xué)成績(jī)是 58/59/98/99 分的同學(xué)

方案一:使用一長(zhǎng)串 OR 連接

SELECT name, math FROM exam_result WHERE math = 58 OR math = 59 OR math = 98 OR math = 99;

方案二:使用簡(jiǎn)潔優(yōu)雅的 IN

SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);

2.2.4 模糊匹配(LIKE)案例

  • 查詢姓孫的同學(xué)(% 代表匹配任意長(zhǎng)度、任意內(nèi)容的字符):
SELECT name FROM exam_result WHERE name LIKE '孫%';

  • 查詢孫某(名字只有兩個(gè)字,且第一個(gè)字是孫)的同學(xué)(_ 僅能代表單個(gè)字符):
SELECT name FROM exam_result WHERE name LIKE '孫_';

2.2.5 字段間的相互比較

我們還可以對(duì)表中同一行的不同字段進(jìn)行橫向比拼。例如:查詢語(yǔ)文成績(jī)優(yōu)于英語(yǔ)成績(jī)的同學(xué)。

SELECT name, chinese, english FROM exam_result WHERE chinese > english;

2.2.6 表達(dá)式與 WHERE 的愛(ài)恨糾葛(??極其重要面試必考)

我們想查詢總分在 200 分以下的同學(xué),有道友可能會(huì)寫(xiě)出這樣的代碼:

-- ? 這是一個(gè)錯(cuò)誤的示范!
SELECT name, (chinese + math + english) 總分 FROM exam_result WHERE 總分 < 200;

運(yùn)行后 MySQL 居然無(wú)情地報(bào)錯(cuò)了:ERROR 1054 (42S22): Unknown column '總分' in 'where clause'。

?? 深度解析:為什么 WHERE 條件里不能使用列別名?

這要從 SQL 語(yǔ)句的底層執(zhí)行先后順序說(shuō)起。當(dāng)你敲下回車(chē)時(shí),MySQL 引擎并不是按照你書(shū)寫(xiě)的“從左到右”順序解析的,它的真正執(zhí)行流程是:

  • FROM:首先確定你要從哪張表拉取數(shù)據(jù)。
  • WHERE:緊接著,根據(jù)過(guò)濾條件從表中篩選出符合要求的行記錄。
  • SELECT:對(duì)于過(guò)濾出來(lái)的行記錄,進(jìn)行投影操作,篩選列,此時(shí)才去解析并計(jì)算別名(如“總分”)。

簡(jiǎn)而言之:執(zhí)行 WHERE 過(guò)濾的時(shí)候,系統(tǒng)根本還沒(méi)執(zhí)行 SELECT 呢!所以系統(tǒng)完全不知道有“總分”這檔子事!

正確寫(xiě)法:必須在 WHERE 條件里重新寫(xiě)完整的表達(dá)式。

SELECT name, (chinese + math + english) 總分 FROM exam_result 
WHERE (chinese + math + english) < 200;

2.3 結(jié)果排序(ORDER BY)

如果不指定排序,我們查詢出來(lái)的結(jié)果顯示順序是無(wú)法保證的。

  • ASC:升序排序(默認(rèn))
  • DESC:降序排序

2.3.1 單字段排序

-- 默認(rèn)升序(從小到大)排列數(shù)學(xué)成績(jī)
SELECT name, math FROM exam_result ORDER BY math;

2.3.2 針對(duì) NULL 值的排序規(guī)則

在排序時(shí),MySQLNULL 視為比任何非空數(shù)值都要小的值。

  • 當(dāng)進(jìn)行 ASC(升序)排序時(shí),所有的 NULL 記錄會(huì)一股腦堆在最上面;
  • 當(dāng)進(jìn)行 DESC(降序)排序時(shí),所有的 NULL 記錄會(huì)跑到最下面。

2.3.3 多字段排序

當(dāng)?shù)谝慌判蜃侄蔚闹党霈F(xiàn)重復(fù)(平局)時(shí),我們可以提供第二排序字段、第三排序字段來(lái)打破平局:

-- 依次按數(shù)學(xué)降序排列;如果數(shù)學(xué)相同,按英語(yǔ)升序;如果英語(yǔ)也相同,按語(yǔ)文升序。
SELECT name, math, english, chinese FROM exam_result
ORDER BY math DESC, english ASC, chinese ASC;

2.3.4 ORDER BY 里的別名使用(??別名可用?。?/h4>

根據(jù)前文關(guān)于執(zhí)行順序的討論,我們?cè)谟?jì)算出別名后才進(jìn)行排序。因此,ORDER BY 子句中是完全可以使用列別名的!

SELECT name, (chinese + math + english) 總分 FROM exam_result
ORDER BY 總分 DESC; -- 順理成章地使用“總分”別名降序排序

2.4 篩選分頁(yè)結(jié)果(LIMIT)

當(dāng)表里有幾十萬(wàn)行數(shù)據(jù)時(shí),全查出來(lái)顯示會(huì)造成客戶端卡死。這時(shí)候我們必須使用 LIMIT 分頁(yè)。 常用的三種語(yǔ)法格式:

-- 格式1(最常用):從位置 s(索引從0開(kāi)始)開(kāi)始,向后拉取 n 條記錄
SELECT ... LIMIT s, n;
-- 格式2:如果不寫(xiě) s,默認(rèn)從 0(第一條)開(kāi)始,拉取 n 條
SELECT ... LIMIT n;
-- 格式3(語(yǔ)義最清晰,推薦!):拉取 n 條記錄,偏移量(起始位置)為 s
SELECT ... LIMIT n OFFSET s;

分頁(yè)實(shí)戰(zhàn)演示(每頁(yè) 3 條記錄)

第 1 頁(yè)(偏移量為 0):

SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3 OFFSET 0;

第 2 頁(yè)(偏移量為 3):

SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3 OFFSET 3;

第 3 頁(yè)(偏移量為 6,數(shù)據(jù)不夠 3 條也沒(méi)關(guān)系,有多少顯示多少):

SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3 OFFSET 6;

?? 性能調(diào)優(yōu)建議:對(duì)未知大小的大表進(jìn)行查詢時(shí),隨手加上一個(gè) LIMIT 1 或者 LIMIT 10 是一個(gè)極佳的職業(yè)習(xí)慣,能有效防止不小心全表查詢導(dǎo)致生產(chǎn)庫(kù)卡死!

三、 Update(更新 & 修改)

UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]

3.1 單字段精準(zhǔn)修改

將孫悟空的數(shù)學(xué)成績(jī)變更為 80 分:

UPDATE exam_result SET math = 80 WHERE name = '孫悟空';

3.2 多字段聯(lián)合修改

一次性修改曹孟德的數(shù)學(xué)成績(jī)?yōu)?60 分,語(yǔ)文成績(jī)?yōu)?70 分:

UPDATE exam_result SET math = 60, chinese = 70 WHERE name = '曹孟德';

3.3 帶排序與分頁(yè)的更新(高階更新)

【經(jīng)典題目】:將總成績(jī)倒數(shù)前三的 3 位同學(xué)的數(shù)學(xué)成績(jī)各自加上 30 分。

?? 注意:MySQL 不支持像 C++ 里面math += 30 這種復(fù)合賦值,必須老老實(shí)實(shí)寫(xiě) math = math + 30

UPDATE exam_result SET math = math + 30
ORDER BY (chinese + math + english) ASC LIMIT 3;

3.4 無(wú)條件的危險(xiǎn)全局更新

-- ?? 危險(xiǎn)動(dòng)作!如果沒(méi)有 WHERE 過(guò)濾條件,全表所有記錄都會(huì)被強(qiáng)行更新!
UPDATE exam_result SET chinese = chinese * 2;

安全警示:生產(chǎn)環(huán)境下不帶 WHEREUPDATE 是重大事故的導(dǎo)火索,執(zhí)行前請(qǐng)務(wù)必反復(fù)確認(rèn)!

四、 Delete(刪除)

4.1 刪除部分匹配行

刪除孫悟空同學(xué)的考試成績(jī)記錄:

DELETE FROM exam_result WHERE name = '孫悟空';

4.2 清空整張表(DELETE VS TRUNCATE)

如果我們需要將一整張表清空,有以下兩個(gè)截然不同的方案:

方案一:使用 DELETE

DELETE FROM for_delete;

方案二:使用 TRUNCATE(截?cái)啾恚?/p>

TRUNCATE TABLE for_truncate;

?? 深度對(duì)比:DELETE 與 TRUNCATE 究竟有何不同?

在面試中,這是??嫉母哳l必背知識(shí)點(diǎn),請(qǐng)牢記以下三點(diǎn)核心差異:

維度

DELETE FROM table_name

TRUNCATE [TABLE] table_name

操作粒度

可以配合 WHERE 刪除特定部分?jǐn)?shù)據(jù)。

只能對(duì)整張表進(jìn)行截?cái)嗲蹇詹僮鳌?/p>

自增 ID 重置

不會(huì)重置自增序列的值,新插入的記錄自增 ID 依然緊接著被刪掉的最大 ID 往后增。

會(huì)重置自增序列,重新從 1 開(kāi)始計(jì)。

底層實(shí)現(xiàn) & 性能

屬于 DML 語(yǔ)句,MySQL 會(huì)逐行物理掃描并打上“刪除標(biāo)記”。因?yàn)樾枰涗洿罅康氖聞?wù)回滾日志(Undo Log),所以速度較慢,支持事務(wù)回滾。

屬于 DDL 語(yǔ)句,MySQL 直接拋棄原本的數(shù)據(jù)頁(yè)并重建一張空表。由于幾乎不產(chǎn)生事務(wù)日志,速度極快,但無(wú)法撤回/回滾。

五、 插入查詢結(jié)果(INSERT ... SELECT)

這是一種非常有用的技術(shù),可以幫我們實(shí)現(xiàn)兩張表之間數(shù)據(jù)的快速遷移、清洗或去重。

實(shí)戰(zhàn):如何優(yōu)雅實(shí)現(xiàn)物理去重?

假如有一張歷史舊表 duplicate_table 里面因?yàn)橄到y(tǒng) Bug 寫(xiě)入了很多重復(fù)數(shù)據(jù),我們?cè)撊绾卧诓粋顒?dòng)骨的情況下只保留一份唯一數(shù)據(jù)?

-- 1. 創(chuàng)建一張全新的臨時(shí)空表,并完全套用舊表的結(jié)構(gòu)
CREATE TABLE no_duplicate_table LIKE duplicate_table;
-- 2. 將去重后的數(shù)據(jù)通過(guò)查詢直接灌入到臨時(shí)表中
INSERT INTO no_duplicate_table SELECT DISTINCT * FROM duplicate_table;
-- 3. 重命名表(這是一個(gè)原子性的改名操作,能夠保證業(yè)務(wù)平滑過(guò)渡)
RENAME TABLE duplicate_table TO old_duplicate_table,
             no_duplicate_table TO duplicate_table;

通過(guò)這種三步走戰(zhàn)略,我們無(wú)需復(fù)雜的程序代碼,就能利用 SQL 自身高效率地完成數(shù)據(jù)整理。

六、 聚合函數(shù)與分組查詢(GROUP BY)

MySQL 為我們提供了豐富的內(nèi)置工具函數(shù),可以跨越多行提取并統(tǒng)計(jì)匯總數(shù)據(jù)。

6.1 常用聚合函數(shù)大集結(jié)

函數(shù)

作用說(shuō)明

特殊性質(zhì)

COUNT([DISTINCT] expr)

返回統(tǒng)計(jì)到的行數(shù)

COUNT(*) 或 COUNT(1) 包括 NULL;指定列名 COUNT(col) 自動(dòng)剔除 NULL

SUM([DISTINCT] expr)

返回指定列的總和

只對(duì)數(shù)值型字段有意義,忽略 NULL

AVG([DISTINCT] expr)

返回平均值

忽略NULL

MAX([DISTINCT] expr)

返回該列的最大值

忽略 NULL

MIN([DISTINCT] expr)

返回該列的最小值

忽略 NULL

經(jīng)典用法

SELECT COUNT(*) FROM students; -- 統(tǒng)計(jì)班級(jí)一共有多少學(xué)生
SELECT COUNT(qq) FROM students; -- 剔除沒(méi)有留 qq(即 NULL)的學(xué)生數(shù)量
SELECT AVG(chinese + math + english) 平均總分 FROM exam_result; -- 計(jì)算全班平均分
SELECT MIN(math) FROM exam_result WHERE math > 70; -- 計(jì)算大于 70 分的數(shù)學(xué)最低分

6.2 分組查詢(GROUP BY)與過(guò)濾(HAVING)

在實(shí)際數(shù)據(jù)分析中,我們最頻繁使用的就是分類匯總。例如經(jīng)典的員工信息表 EMP(包含薪水 sal、職位 job、部門(mén)編號(hào) deptno)。

6.2.1 統(tǒng)計(jì)每個(gè)部門(mén)的平均工資和最高工資:

SELECT deptno, AVG(sal), MAX(sal) FROM EMP GROUP BY deptno;

6.2.2 統(tǒng)計(jì)每個(gè)部門(mén)中,不同崗位(每種崗位)的平均工資和最低工資:

-- 在 GROUP BY 后面指定多個(gè)列,表示按多維度組合進(jìn)行細(xì)分分組
SELECT deptno, job, AVG(sal), MIN(sal) FROM EMP GROUP BY deptno, job;

6.2.3 HAVING 與 WHERE 的決戰(zhàn)(核心面試題)

如果我們想要篩選出“平均工資低于 2000 的部門(mén)及它的平均工資”,很多新手會(huì)習(xí)慣性地寫(xiě)成:

-- ? 錯(cuò)誤做法:WHERE 報(bào)錯(cuò)!
SELECT deptno, AVG(sal) FROM EMP WHERE AVG(sal) < 2000 GROUP BY deptno;

因?yàn)?WHERE 只能針對(duì)原始表中的物理列進(jìn)行篩選。一旦需要對(duì)聚合分組(GROUP BY)后的統(tǒng)計(jì)結(jié)果進(jìn)行再過(guò)濾,我們必須使用專用的 HAVING 子句:

-- ? 正確做法:使用 HAVING
SELECT deptno, AVG(sal) AS myavg FROM EMP GROUP BY deptno HAVING myavg < 2000;

?? 核心考點(diǎn):WHERE 與 HAVING 的本質(zhì)區(qū)別

  • 執(zhí)行時(shí)機(jī)不同:WHERE 發(fā)生在 GROUP BY 之前,負(fù)責(zé)篩選原始行;HAVING 發(fā)生在 GROUP BY 之后,負(fù)責(zé)篩選匯總后的分組。
  • 過(guò)濾對(duì)象不同:WHERE 后面不能跟聚合函數(shù)(如 SUM、AVG);而 HAVING 的后方通常伴隨著聚合函數(shù)的判斷條件。

七、 終極奧義:SQL 關(guān)鍵字執(zhí)行順序全貌

要想寫(xiě)出完美避坑、效率極佳的 SQL 語(yǔ)句,你必須要背得滾瓜爛熟的一張圖,就是 SQL 各大關(guān)鍵字在 MySQL 內(nèi)部的真實(shí)執(zhí)行邏輯先后順序

請(qǐng)務(wù)必將這個(gè)執(zhí)行鏈路銘記于心。在分析復(fù)雜的慢 SQL 查詢、別名解析等問(wèn)題時(shí),這套執(zhí)行鏈條就是你最強(qiáng)大的破案武器!

結(jié)語(yǔ)

恭喜你!讀到這里,你已經(jīng)成功將 MySQL CRUD 的核心操作、避坑細(xì)節(jié)、底層的執(zhí)行順序原理全部收入囊中。數(shù)據(jù)庫(kù)技術(shù)是一門(mén)注重實(shí)操的學(xué)問(wèn),建議大家在自己的測(cè)試環(huán)境里把這些 SQL 語(yǔ)句手敲一遍。

到此這篇關(guān)于MySQL從零掌握 CRUD 核心操作大全:詳解增刪改查、聚合過(guò)濾與實(shí)戰(zhàn)避坑指南的文章就介紹到這了,更多相關(guān)mysql crud增刪改查內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL數(shù)據(jù)庫(kù)設(shè)計(jì)實(shí)戰(zhàn)之如何從需求到建表(完整流程)

    MySQL數(shù)據(jù)庫(kù)設(shè)計(jì)實(shí)戰(zhàn)之如何從需求到建表(完整流程)

    這篇文章給大家介紹MySQL數(shù)據(jù)庫(kù)設(shè)計(jì)實(shí)戰(zhàn)之如何從需求到建表,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • MySQL8.0+版本1045錯(cuò)誤的問(wèn)題及解決辦法

    MySQL8.0+版本1045錯(cuò)誤的問(wèn)題及解決辦法

    這篇文章主要介紹了MySQL8.0+版本1045錯(cuò)誤解決辦法,使用命令行登錄MySQL報(bào)錯(cuò)1045 Access denied for user ‘root’@‘localhost’ (using password:YES),折騰半天才解決問(wèn)題,需要的朋友可以參考下
    2022-08-08
  • Mysql中自定義函數(shù)的創(chuàng)建和執(zhí)行方式

    Mysql中自定義函數(shù)的創(chuàng)建和執(zhí)行方式

    這篇文章主要介紹了Mysql中自定義函數(shù)的創(chuàng)建和執(zhí)行方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • MYSQL 5.6 從庫(kù)復(fù)制的部署和監(jiān)控的實(shí)現(xiàn)

    MYSQL 5.6 從庫(kù)復(fù)制的部署和監(jiān)控的實(shí)現(xiàn)

    這篇文章主要介紹了MYSQL 5.6 從庫(kù)復(fù)制的部署和監(jiān)控的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Mysql數(shù)據(jù)庫(kù)實(shí)現(xiàn)多字段過(guò)濾的方法

    Mysql數(shù)據(jù)庫(kù)實(shí)現(xiàn)多字段過(guò)濾的方法

    這篇文章主要介紹了Mysql數(shù)據(jù)庫(kù)實(shí)現(xiàn)多字段過(guò)濾的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-07-07
  • MySQL中“:=”和“=”的區(qū)別淺析

    MySQL中“:=”和“=”的區(qū)別淺析

    這篇文章主要給大家介紹了關(guān)于MySQL中":="和"="區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • MySQL之select、distinct、limit的使用

    MySQL之select、distinct、limit的使用

    這篇文章主要介紹了MySQL之select、distinct、limit的使用,下面文章圍繞select、distinct、limit的相關(guān)資料展開(kāi)聚集內(nèi)容,需要的朋友可以參考一下
    2021-11-11
  • MySQL8新特性:降序索引詳解

    MySQL8新特性:降序索引詳解

    在數(shù)據(jù)庫(kù)中我們一般都會(huì)對(duì)一些字段進(jìn)行索引操作,這樣可以提升數(shù)據(jù)的查詢速度,下面這篇文章主要給大家介紹了關(guān)于MySQL8新特性:降序索引的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • mysql事務(wù)隔離級(jí)別詳解

    mysql事務(wù)隔離級(jí)別詳解

    MySQL事務(wù)隔離級(jí)別是指在多個(gè)事務(wù)同時(shí)執(zhí)行時(shí),數(shù)據(jù)庫(kù)系統(tǒng)如何處理這些事務(wù)之間的相互影響。MySQL提供了四種隔離級(jí)別:讀未提交、讀已提交、可重復(fù)讀和串行化。每種隔離級(jí)別都有其優(yōu)缺點(diǎn),需要根據(jù)具體情況選擇合適的級(jí)別。
    2023-06-06
  • MySQL存儲(chǔ)過(guò)程的創(chuàng)建、調(diào)用與管理詳解

    MySQL存儲(chǔ)過(guò)程的創(chuàng)建、調(diào)用與管理詳解

    這篇文章主要給大家介紹了關(guān)于MySQL存儲(chǔ)過(guò)程的創(chuàng)建、調(diào)用與管理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評(píng)論

永吉县| 澳门| 资阳市| 曲松县| 始兴县| 万山特区| 腾冲县| 张家界市| 呼伦贝尔市| 赫章县| 呼伦贝尔市| 金溪县| 恩施市| 浪卡子县| 文登市| 丰宁| 开封县| 丁青县| 荥经县| 安塞县| 隆德县| 和平区| 二连浩特市| 宜阳县| 宁乡县| 湖北省| 淮南市| 青浦区| 化隆| 唐山市| 黄骅市| 甘孜| 务川| 法库县| 沧州市| 淮南市| 隆昌县| 正阳县| 宜川县| 司法| 贞丰县|