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

MySQL核心必會之表的增刪改查(CRUD)實戰(zhàn)指南

 更新時間:2026年07月17日 11:39:42   作者:時間的拾荒人  
CRUD 是數(shù)據(jù)庫操作的核心,它代表了 Create(創(chuàng)建)、Retrieve(讀?。?、Update(更新) 和 Delete(刪除) 這四種基本操作,本文將基于 MySQL,通過大量實戰(zhàn)案例,帶你徹底掌握表的增刪改查,快跟隨小編一起學(xué)習(xí)起來吧

1. 引言

CRUD 是數(shù)據(jù)庫操作的核心,它代表了 Create(創(chuàng)建)Retrieve(讀?。?/strong>、Update(更新)Delete(刪除) 這四種基本操作。無論你是初學(xué)者還是準(zhǔn)備面試,熟練掌握 CRUD 都是必備技能。

本文將基于 MySQL,通過大量實戰(zhàn)案例,帶你徹底掌握表的增刪改查。文章內(nèi)容詳盡,代碼完整,并配有經(jīng)典面試題,助你輕松應(yīng)對面試。

2. Create(創(chuàng)建數(shù)據(jù))

2.1 語法

INSERT [INTO] table_name
    [(column [, column] ...)]
    VALUES (value_list) [, (value_list)] ...

value_list: value, [, value] …

2.2 案例實操

首先,我們創(chuàng)建一張學(xué)生表作為操作對象:

-- 創(chuàng)建一張學(xué)生表
CREATE TABLE students (
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    sn INT NOT NULL UNIQUE COMMENT '學(xué)號',
    name VARCHAR(20) NOT NULL,
    qq VARCHAR(20)
);

2.2.1 單行數(shù)據(jù) + 全列插入

-- 插入一條記錄,value_list 數(shù)量必須和定義表的列的數(shù)量及順序一致
INSERT INTO students VALUES (101, 10001, '孫悟空', '11111');
Query OK, 1 row affected (0.02 sec)

注意:這里在插入的時候,也可以不用指定 id(當(dāng)然,那時候就需要明確插入數(shù)據(jù)到那些列了),那么 MySQL 會使用默認(rèn)的值進(jìn)行自增。

INSERT INTO students VALUES (100, 10000, '唐三藏', NULL);
Query OK, 1 row affected (0.02 sec)

-- 查看插入結(jié)果
SELECT * FROM students;
+-----+-------+-----------+-------+
| id  | sn    | name      | qq    |
+-----+-------+-----------+-------+
| 100 | 10000 | 唐三藏    | NULL  |
| 101 | 10001 | 孫悟空    | 11111 |
+-----+-------+-----------+-------+
2 rows in set (0.00 sec)

2.2.2 多行數(shù)據(jù) + 指定列插入

-- 插入兩條記錄,value_list 數(shù)量必須和指定列數(shù)量及順序一致
INSERT INTO students (id, sn, name) VALUES
    (102, 20001, '曹孟德'),
    (103, 20002, '孫仲謀');
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

-- 查看插入結(jié)果
SELECT * FROM students;
+-----+-------+-----------+-------+
| id  | sn    | name      | qq    |
+-----+-------+-----------+-------+
| 100 | 10000 | 唐三藏    | NULL  |
| 101 | 10001 | 孫悟空    | 11111 |
| 102 | 20001 | 曹孟德    | NULL  |
| 103 | 20002 | 孫仲謀    | NULL  |
+-----+-------+-----------+-------+
4 rows in set (0.00 sec)

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

當(dāng)由于 主鍵 或者 唯一鍵 對應(yīng)的值已經(jīng)存在而導(dǎo)致插入失敗時,可以選擇性地進(jìn)行同步更新操作。

語法:

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

案例:

-- 主鍵沖突
INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大師');
ERROR 1062 (23000): Duplicate entry '100' for key 'PRIMARY'

-- 唯一鍵沖突
INSERT INTO students (sn, name) VALUES (20001, '曹阿瞞');
ERROR 1062 (23000): Duplicate entry '20001' for key 'sn'

-- 使用 ON DUPLICATE KEY UPDATE 解決沖突
INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大師')
    ON DUPLICATE KEY UPDATE sn = 10010, name = '唐大師';
Query OK, 2 rows affected (0.47 sec)

影響行數(shù)說明

  • 0 row affected: 表中有沖突數(shù)據(jù),但沖突數(shù)據(jù)的值和 update 的值相等
  • 1 row affected: 表中沒有沖突數(shù)據(jù),數(shù)據(jù)被 插入
  • 2 row affected: 表中有沖突數(shù)據(jù),并且數(shù)據(jù)已經(jīng)被更新
-- 通過 MySQL 函數(shù)獲取受到影響的數(shù)據(jù)行數(shù)
SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           2 |
+-------------+

2.4 替換(REPLACE)

語法:

REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞞');
Query OK, 2 rows affected (0.00 sec)

REPLACE 的工作原理

  • 主鍵或者唯一鍵沒有沖突,則直接插入;
  • 主鍵或者唯一鍵如果沖突,則刪除后再插入。

影響行數(shù)說明

  • 1 row affected: 表中沒有沖突數(shù)據(jù),數(shù)據(jù)被 插入
  • 2 row affected: 表中有沖突數(shù)據(jù),刪除后重新插入

3. Retrieve(讀取數(shù)據(jù))

檢索(查詢)是 SQL 中使用頻率最高的操作。

3.1 語法

SELECT
    [DISTINCT] {* | {column [, column] ...}
    [FROM table_name]
    [WHERE ...]      -- 篩選條件
    [ORDER BY column [ASC | DESC], ...]
    [LIMIT ...]

3.2 案例實操

首先,創(chuàng)建一張考試成績表并插入測試數(shù)據(jù):

-- 創(chuàng)建表結(jié)構(gòu)
CREATE TABLE exam_result (
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL COMMENT '同學(xué)姓名',
    chinese float DEFAULT 0.0 COMMENT '語文成績',
    math float DEFAULT 0.0 COMMENT '數(shù)學(xué)成績',
    english float DEFAULT 0.0 COMMENT '英語成績'
);

-- 插入測試數(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);
Query OK, 7 rows affected (0.00 sec)
Records: 7  Duplicates: 0  Warnings: 0

3.3 SELECT 列

3.3.1 全列查詢

SELECT * FROM exam_result;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |      67 |   98 |      56 |
|  2 | 孫悟空    |      87 |   78 |      77 |
|  3 | 豬悟能    |      88 |   98 |      90 |
|  4 | 曹孟德    |      82 |   84 |      67 |
|  5 | 劉玄德    |      55 |   85 |      45 |
|  6 | 孫權(quán)      |      70 |   73 |      78 |
|  7 | 宋公明    |      75 |   65 |      30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)

注意:通常情況下不建議使用 * 進(jìn)行全列查詢。

  1. 查詢的列越多,意味著需要傳輸?shù)臄?shù)據(jù)量越大;
  2. 可能會影響到索引的使用(索引待后面課程講解)。

3.3.2 指定列查詢

-- 指定列的順序不需要按定義表的順序來
SELECT id, name, english FROM exam_result;
+----+-----------+---------+
| id | name      | english |
+----+-----------+---------+
|  1 | 唐三藏    |      56 |
|  2 | 孫悟空    |      77 |
|  3 | 豬悟能    |      90 |
|  4 | 曹孟德    |      67 |
|  5 | 劉玄德    |      45 |
|  6 | 孫權(quán)      |      78 |
|  7 | 宋公明    |      30 |
+----+-----------+---------+
7 rows in set (0.00 sec)

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

-- 表達(dá)式不包含字段
SELECT id, name, 10 FROM exam_result;
+----+-----------+----+
| id | name      | 10 |
+----+-----------+----+
|  1 | 唐三藏    | 10 |
|  2 | 孫悟空    | 10 |
|  3 | 豬悟能    | 10 |
|  4 | 曹孟德    | 10 |
|  5 | 劉玄德    | 10 |
|  6 | 孫權(quán)      | 10 |
|  7 | 宋公明    | 10 |
+----+-----------+----+
7 rows in set (0.00 sec)

-- 表達(dá)式包含一個字段
SELECT id, name, english + 10 FROM exam_result;
+----+-----------+-------------+
| id | name      | english + 10 |
+----+-----------+-------------+
|  1 | 唐三藏    |          66 |
|  2 | 孫悟空    |          87 |
|  3 | 豬悟能    |         100 |
|  4 | 曹孟德    |          77 |
|  5 | 劉玄德    |          55 |
|  6 | 孫權(quán)      |          88 |
|  7 | 宋公明    |          40 |
+----+-----------+-------------+
7 rows in set (0.00 sec)

-- 表達(dá)式包含多個字段
SELECT id, name, chinese + math + english FROM exam_result;
+----+-----------+-------------------------+
| id | name      | chinese + math + english |
+----+-----------+-------------------------+
|  1 | 唐三藏    |                     221 |
|  2 | 孫悟空    |                     242 |
|  3 | 豬悟能    |                     276 |
|  4 | 曹孟德    |                     233 |
|  5 | 劉玄德    |                     185 |
|  6 | 孫權(quán)      |                     221 |
|  7 | 宋公明    |                     170 |
+----+-----------+-------------------------+
7 rows in set (0.00 sec)

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

語法:

SELECT column [AS] alias_name [...] FROM table_name;

案例:

SELECT id, name, chinese + math + english 總分 FROM exam_result;
+----+-----------+--------+
| id | name      | 總分   |
+----+-----------+--------+
|  1 | 唐三藏    |    221 |
|  2 | 孫悟空    |    242 |
|  3 | 豬悟能    |    276 |
|  4 | 曹孟德    |    233 |
|  5 | 劉玄德    |    185 |
|  6 | 孫權(quán)      |    221 |
|  7 | 宋公明    |    170 |
+----+-----------+--------+
7 rows in set (0.00 sec)

3.3.5 結(jié)果去重

-- 98 分重復(fù)了
SELECT math FROM exam_result;
+--------+
| math   |
+--------+
|     98 |
|     78 |
|     98 |
|     84 |
|     85 |
|     73 |
|     65 |
+--------+
7 rows in set (0.00 sec)

-- 去重結(jié)果
SELECT DISTINCT math FROM exam_result;
+--------+
| math   |
+--------+
|     98 |
|     78 |
|     84 |
|     85 |
|     73 |
|     65 |
+--------+
6 rows in set (0.00 sec)

3.4 WHERE 條件

3.4.1 比較運(yùn)算符

運(yùn)算符說明
>, >=, <, <=大于,大于等于,小于,小于等于
=等于,NULL 不安全,例如 NULL = NULL 的結(jié)果是 NULL
<=>等于,NULL 安全,例如 NULL <=> NULL 的結(jié)果是 TRUE(1)
!=, <>不等于
BETWEEN a0 AND a1范圍匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1)
IN (option, ...)如果是 option 中的任意一個,返回 TRUE(1)
IS NULLNULL
IS NOT NULL不是 NULL
LIKE模糊匹配。% 表示任意多個(包括 0 個)任意字符;_ 表示任意一個字符

3.4.2 邏輯運(yùn)算符

運(yùn)算符說明
AND多個條件必須都為 TRUE(1),結(jié)果才是 TRUE(1)
OR任意一個條件為 TRUE(1),結(jié)果為 TRUE(1)
NOT條件為 TRUE(1),結(jié)果為 FALSE(0)

3.4.3 案例實操

① 英語不及格的同學(xué)及英語成績 ( < 60 )

SELECT name, english FROM exam_result WHERE english < 60;
+-----------+---------+
| name      | english |
+-----------+---------+
| 唐三藏    |      56 |
| 劉玄德    |      45 |
| 宋公明    |      30 |
+-----------+---------+
3 rows in set (0.01 sec)

② 語文成績在 [80, 90] 分的同學(xué)及語文成績

-- 使用 AND 進(jìn)行條件連接
SELECT name, chinese FROM exam_result WHERE chinese >= 80 AND chinese <= 90;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 孫悟空    |      87 |
| 豬悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
3 rows in set (0.00 sec)

-- 使用 BETWEEN ... AND ... 條件
SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 孫悟空    |      87 |
| 豬悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
3 rows in set (0.00 sec)

③ 數(shù)學(xué)成績是 58 或者 59 或者 98 或者 99 分的同學(xué)及數(shù)學(xué)成績

-- 使用 OR 進(jìn)行條件連接
SELECT name, math FROM exam_result
 WHERE math = 58
 OR math = 59
 OR math = 98
 OR math = 99;
+-----------+------+
| name      | math |
+-----------+------+
| 唐三藏    |   98 |
| 豬悟能    |   98 |
+-----------+------+
2 rows in set (0.01 sec)

-- 使用 IN 條件
SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);
+-----------+------+
| name      | math |
+-----------+------+
| 唐三藏    |   98 |
| 豬悟能    |   98 |
+-----------+------+
2 rows in set (0.00 sec)

④ 姓孫的同學(xué) 及 孫某同學(xué)

-- % 匹配任意多個(包括 0 個)任意字符
SELECT name FROM exam_result WHERE name LIKE '孫%';
+-----------+
| name      |
+-----------+
| 孫悟空    |
| 孫權(quán)      |
+-----------+
2 rows in set (0.00 sec)

-- _ 匹配嚴(yán)格的一個任意字符
SELECT name FROM exam_result WHERE name LIKE '孫_';
+--------+
| name   |
+--------+
| 孫權(quán)   |
+--------+
1 row in set (0.00 sec)

⑤ 語文成績好于英語成績的同學(xué)

SELECT name, chinese, english FROM exam_result WHERE chinese > english;
+-----------+---------+---------+
| name      | chinese | english |
+-----------+---------+---------+
| 唐三藏    |      67 |      56 |
| 孫悟空    |      87 |      77 |
| 曹孟德    |      82 |      67 |
| 劉玄德    |      55 |      45 |
| 宋公明    |      75 |      30 |
+-----------+---------+---------+
5 rows in set (0.00 sec)

⑥ 總分在 200 分以下的同學(xué)

-- WHERE 條件中使用表達(dá)式
-- 別名不能用在 WHERE 條件中
SELECT name, chinese + math + english 總分 FROM exam_result
    WHERE chinese + math + english < 200;
+-----------+--------+
| name      | 總分   |
+-----------+--------+
| 劉玄德    |    185 |
| 宋公明    |    170 |
+-----------+--------+
2 rows in set (0.00 sec)

⑦ 語文成績 > 80 并且不姓孫的同學(xué)

-- AND 與 NOT 的使用
SELECT name, chinese FROM exam_result
 WHERE chinese > 80 AND name NOT LIKE '孫%';
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 豬悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
2 rows in set (0.00 sec)

⑧ 孫某同學(xué),否則要求總成績 > 200 并且 語文成績 < 數(shù)學(xué)成績 并且 英語成績 > 80

-- NULL不參與運(yùn)算,即NULLh和任何數(shù)據(jù)比較都是false
-- 綜合性查詢
SELECT name, chinese, math, english, chinese + math + english 總分
FROM exam_result
WHERE name LIKE '孫_' OR (
    chinese + math + english > 200 AND chinese < math AND english > 80
);
+-----------+---------+------+---------+--------+
| name      | chinese | math | english | 總分   |
+-----------+---------+------+---------+--------+
| 豬悟能    |      88 |   98 |      90 |    276 |
| 孫權(quán)      |      70 |   73 |      78 |    221 |
+-----------+---------+------+---------+--------+
2 rows in set (0.00 sec)

⑨ NULL 的查詢

-- 查詢 students 表
SELECT * FROM students;
+-----+-------+-----------+-------+
| id  | sn    | name      | qq    |
+-----+-------+-----------+-------+
| 100 | 10010 | 唐大師    | NULL  |
| 101 | 10001 | 孫悟空    | 11111 |
| 103 | 20002 | 孫仲謀    | NULL  |
| 104 | 20001 | 曹阿瞞    | NULL  |
+-----+-------+-----------+-------+
4 rows in set (0.00 sec)

-- 查詢 qq 號已知的同學(xué)姓名
SELECT name, qq FROM students WHERE qq IS NOT NULL;
+-----------+-------+
| name      | qq    |
+-----------+-------+
| 孫悟空    | 11111 |
+-----------+-------+
1 row in set (0.00 sec)

-- NULL 和 NULL 的比較,= 和 <=> 的區(qū)別
SELECT NULL = NULL, NULL = 1, NULL = 0;
+-------------+----------+----------+
| NULL = NULL | NULL = 1 | NULL = 0 |
+-------------+----------+----------+
|        NULL |     NULL |     NULL |
+-------------+----------+----------+
1 row in set (0.00 sec)

SELECT NULL <=> NULL, NULL <=> 1, NULL <=> 0;
+---------------+------------+------------+
| NULL <=> NULL | NULL <=> 1 | NULL <=> 0 |
+---------------+------------+------------+
|             1 |          0 |          0 |
+---------------+------------+------------+
1 row in set (0.00 sec)

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

語法:

-- MySQL引號中不區(qū)分單雙引號
SELECT ... FROM table_name [WHERE ...]
 ORDER BY column [ASC|DESC], [...]
  • ASC 為升序(從小到大)
  • DESC 為降序(從大到?。?/li>
  • 默認(rèn)為 ASC

注意:沒有 ORDER BY 子句的查詢,返回的順序是未定義的,永遠(yuǎn)不要依賴這個順序。

3.5.1 同學(xué)及數(shù)學(xué)成績,按數(shù)學(xué)成績升序顯示

SELECT name, math FROM exam_result ORDER BY math;
+-----------+------+
| name      | math |
+-----------+------+
| 宋公明    |   65 |
| 孫權(quán)      |   73 |
| 孫悟空    |   78 |
| 曹孟德    |   84 |
| 劉玄德    |   85 |
| 唐三藏    |   98 |
| 豬悟能    |   98 |
+-----------+------+
7 rows in set (0.00 sec)

3.5.2 同學(xué)及 qq 號,按 qq 號排序顯示

-- NULL 視為比任何值都小,升序出現(xiàn)在最上面
SELECT name, qq FROM students ORDER BY qq;
+-----------+-------+
| name      | qq    |
+-----------+-------+
| 唐大師    | NULL  |
| 孫仲謀    | NULL  |
| 曹阿瞞    | NULL  |
| 孫悟空    | 11111 |
+-----------+-------+
4 rows in set (0.00 sec)

-- NULL 視為比任何值都小,降序出現(xiàn)在最下面
SELECT name, qq FROM students ORDER BY qq DESC;
+-----------+-------+
| name      | qq    |
+-----------+-------+
| 孫悟空    | 11111 |
| 唐大師    | NULL  |
| 孫仲謀    | NULL  |
| 曹阿瞞    | NULL  |
+-----------+-------+
4 rows in set (0.00 sec)

3.5.3 查詢同學(xué)各門成績,依次按數(shù)學(xué)降序,英語升序,語文升序的方式顯示

-- 多字段排序,排序優(yōu)先級隨書寫順序
SELECT name, math, english, chinese FROM exam_result
 ORDER BY math DESC, english, chinese;
+-----------+------+---------+---------+
| name      | math | english | chinese |
+-----------+------+---------+---------+
| 唐三藏    |   98 |      56 |      67 |
| 豬悟能    |   98 |      90 |      88 |
| 劉玄德    |   85 |      45 |      55 |
| 曹孟德    |   84 |      67 |      82 |
| 孫悟空    |   78 |      77 |      87 |
| 孫權(quán)      |   73 |      78 |      70 |
| 宋公明    |   65 |      30 |      75 |
+-----------+------+---------+---------+
7 rows in set (0.00 sec)

3.5.4 查詢同學(xué)及總分,由高到低

-- ORDER BY 中可以使用表達(dá)式
SELECT name, chinese + english + math FROM exam_result
ORDER BY chinese + english + math DESC;
+-----------+-------------------------+
| name | chinese + english + math |
+-----------+-------------------------+
| 豬悟能 | 										276 |
| 孫悟空 | 										242 |
| 曹孟德 | 										233 |
| 唐三藏 | 										221 |
| 孫權(quán) | 										221 |
| 劉玄德 | 										185 |
| 宋公明 |										 170 |
+-----------+-------------------------+
7 rows in set (0.00 sec)
-- ORDER BY 子句中可以使用列別名
SELECT name, chinese + english + math 總分 FROM exam_result
ORDER BY 總分 DESC;
+-----------+--------+
| name | 總分 |
+-----------+--------+
| 豬悟能 | 276 |
| 孫悟空 | 242 |
| 曹孟德 | 233 |
| 唐三藏 | 221 |
| 孫權(quán) | 	221 |
| 劉玄德 | 185 |
| 宋公明 | 170 |
+-----------+--------+
7 rows in set (0.00 sec)
  • order by 語句在total語句之后,所以這里能使用別名
  • order by 需要先有數(shù)據(jù),再排序,即order by 指令是在將數(shù)據(jù)篩選之后再排序

3.5.5 查詢姓孫的同學(xué)或者姓曹的同學(xué)數(shù)學(xué)成績,結(jié)果按數(shù)學(xué)成績由高到低顯示

-- 結(jié)合 WHERE 子句 和 ORDER BY 子句
SELECT name, math FROM exam_result
WHERE name LIKE '孫%' OR name LIKE '曹%'
ORDER BY math DESC;
+-----------+--------+
| name | math |
+-----------+--------+
| 曹孟德 | 84 |
| 孫悟空 | 78 |
| 孫權(quán) | 73 |
+-----------+--------+
3 rows in set (0.00 sec)

3.6 篩選分頁結(jié)果(LIMIT)

語法:

-- 從 0 開始,篩選 n 條結(jié)果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;

-- 從 s 開始,篩選 n 條結(jié)果,比第二種用法更明確,建議使用
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s;

建議:對未知表進(jìn)行查詢時,最好加一條 LIMIT 1,避免因為表中數(shù)據(jù)過大,查詢?nèi)頂?shù)據(jù)導(dǎo)致數(shù)據(jù)庫卡死。

1.需要數(shù)據(jù)才能排序

2.只有數(shù)據(jù)準(zhǔn)備好了,你才能顯示,limit的本質(zhì)功能是“顯示”,即limit的執(zhí)行順序更靠后。

3.s是開始位置(下標(biāo)從0開始)

4.n是步長,從指定位置開始,連續(xù)讀取多少條記錄

5.offset:開始位置,n為連續(xù)讀取記錄數(shù)

案例:按 id 進(jìn)行分頁,每頁 3 條記錄,分別顯示第 1、2、3 頁

-- 第 1 頁
SELECT id, name, math, english, chinese FROM exam_result
 ORDER BY id LIMIT 3 OFFSET 0;
+----+-----------+------+---------+---------+
| id | name      | math | english | chinese |
+----+-----------+------+---------+---------+
|  1 | 唐三藏    |   98 |      56 |      67 |
|  2 | 孫悟空    |   78 |      77 |      87 |
|  3 | 豬悟能    |   98 |      90 |      88 |
+----+-----------+------+---------+---------+
3 rows in set (0.02 sec)

-- 第 2 頁
SELECT id, name, math, english, chinese FROM exam_result
 ORDER BY id LIMIT 3 OFFSET 3;
+----+-----------+------+---------+---------+
| id | name      | math | english | chinese |
+----+-----------+------+---------+---------+
|  4 | 曹孟德    |   84 |      67 |      82 |
|  5 | 劉玄德    |   85 |      45 |      55 |
|  6 | 孫權(quán)      |   73 |      78 |      70 |
+----+-----------+------+---------+---------+
3 rows in set (0.00 sec)

-- 第 3 頁,如果結(jié)果不足 3 個,不會有影響
SELECT id, name, math, english, chinese FROM exam_result
 ORDER BY id LIMIT 3 OFFSET 6;
+----+-----------+------+---------+---------+
| id | name      | math | english | chinese |
+----+-----------+------+---------+---------+
|  7 | 宋公明    |   65 |      30 |      75 |
+----+-----------+------+---------+---------+
1 row in set (0.00 sec)

4. Update(更新數(shù)據(jù))

4.1 語法

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

對查詢到的結(jié)果進(jìn)行列值更新。

4.2 案例實操

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

-- 查看原數(shù)據(jù)
SELECT name, math FROM exam_result WHERE name = '孫悟空';
+-----------+------+
| name      | math |
+-----------+------+
| 孫悟空    |   78 |
+-----------+------+
1 row in set (0.00 sec)

-- 數(shù)據(jù)更新
UPDATE exam_result SET math = 80 WHERE name = '孫悟空';
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

-- 查看更新后數(shù)據(jù)
SELECT name, math FROM exam_result WHERE name = '孫悟空';
+-----------+------+
| name      | math |
+-----------+------+
| 孫悟空    |   80 |
+-----------+------+
1 row in set (0.00 sec)

4.2.2 將曹孟德同學(xué)的數(shù)學(xué)成績變更為 60 分,語文成績變更為 70 分

-- 查看原數(shù)據(jù)
SELECT name, math, chinese FROM exam_result WHERE name = '曹孟德';
+-----------+------+---------+
| name      | math | chinese |
+-----------+------+---------+
| 曹孟德    |   84 |      82 |
+-----------+------+---------+
1 row in set (0.00 sec)

-- 數(shù)據(jù)更新
UPDATE exam_result SET math = 60, chinese = 70 WHERE name = '曹孟德';
Query OK, 1 row affected (0.14 sec)
Rows matched: 1  Changed: 1  Warnings: 0

-- 查看更新后數(shù)據(jù)
SELECT name, math, chinese FROM exam_result WHERE name = '曹孟德';
+-----------+------+---------+
| name      | math | chinese |
+-----------+------+---------+
| 曹孟德    |   60 |      70 |
+-----------+------+---------+
1 row in set (0.00 sec)

4.2.3 將總成績倒數(shù)前三的 3 位同學(xué)的數(shù)學(xué)成績加上 30 分

-- 查看原數(shù)據(jù)
-- 別名可以在 ORDER BY 中使用
SELECT name, math, chinese + math + english 總分 FROM exam_result
 ORDER BY 總分 LIMIT 3;
+-----------+------+--------+
| name      | math | 總分   |
+-----------+------+--------+
| 宋公明    |   65 |    170 |
| 劉玄德    |   85 |    185 |
| 曹孟德    |   60 |    197 |
+-----------+------+--------+
3 rows in set (0.00 sec)

-- 數(shù)據(jù)更新,不支持 math += 30 這種語法
UPDATE exam_result SET math = math + 30
 ORDER BY chinese + math + english LIMIT 3;

-- 查看更新后數(shù)據(jù)
SELECT name, math, chinese + math + english 總分 FROM exam_result
 WHERE name IN ('宋公明', '劉玄德', '曹孟德');
+-----------+------+--------+
| name      | math | 總分   |
+-----------+------+--------+
| 曹孟德    |   90 |    227 |
| 劉玄德    |  115 |    215 |
| 宋公明    |   95 |    200 |
+-----------+------+--------+
3 rows in set (0.00 sec)

4.2.4 將所有同學(xué)的語文成績更新為原來的 2 倍

注意:更新全表的語句慎用!

-- 查看原數(shù)據(jù)
SELECT * FROM exam_result;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |      67 |   98 |      56 |
|  2 | 孫悟空    |      87 |   80 |      77 |
|  3 | 豬悟能    |      88 |   98 |      90 |
|  4 | 曹孟德    |      70 |   90 |      67 |
|  5 | 劉玄德    |      55 |  115 |      45 |
|  6 | 孫權(quán)      |      70 |   73 |      78 |
|  7 | 宋公明    |      75 |   95 |      30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)

-- 數(shù)據(jù)更新
UPDATE exam_result SET chinese = chinese * 2;
Query OK, 7 rows affected (0.00 sec)
Rows matched: 7  Changed: 7  Warnings: 0

-- 查看更新后數(shù)據(jù)
SELECT * FROM exam_result;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |     134 |   98 |      56 |
|  2 | 孫悟空    |     174 |   80 |      77 |
|  3 | 豬悟能    |     176 |   98 |      90 |
|  4 | 曹孟德    |     140 |   90 |      67 |
|  5 | 劉玄德    |     110 |  115 |      45 |
|  6 | 孫權(quán)      |     140 |   73 |      78 |
|  7 | 宋公明    |     150 |   95 |      30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)

5. Delete(刪除數(shù)據(jù))

5.1 刪除數(shù)據(jù)(DELETE)

語法:

DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]

5.1.1 刪除孫悟空同學(xué)的考試成績

-- 查看原數(shù)據(jù)
SELECT * FROM exam_result WHERE name = '孫悟空';
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  2 | 孫悟空    |    174 |   80 |      77 |
+----+-----------+---------+------+---------+
1 row in set (0.00 sec)

-- 刪除數(shù)據(jù)
DELETE FROM exam_result WHERE name = '孫悟空';
Query OK, 1 row affected (0.17 sec)

-- 查看刪除結(jié)果
SELECT * FROM exam_result WHERE name = '孫悟空';
Empty set (0.00 sec)

5.1.2 刪除整張表數(shù)據(jù)

注意:刪除整表操作要慎用!

-- 準(zhǔn)備測試表
CREATE TABLE for_delete (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20)
);
Query OK, 0 rows affected (0.16 sec)

-- 插入測試數(shù)據(jù)
INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');
Query OK, 3 rows affected (1.05 sec)
Records: 3  Duplicates: 0  Warnings: 0

-- 查看測試數(shù)據(jù)
SELECT * FROM for_delete;
+----+------+
| id | name |
+----+------+
|  1 | A    |
|  2 | B    |
|  3 | C    |
+----+------+
3 rows in set (0.00 sec)

-- 刪除整表數(shù)據(jù)
DELETE FROM for_delete;
Query OK, 3 rows affected (0.00 sec)

-- 查看刪除結(jié)果
SELECT * FROM for_delete;
Empty set (0.00 sec)

-- 再插入一條數(shù)據(jù),自增 id 在原值上增長
INSERT INTO for_delete (name) VALUES ('D');
Query OK, 1 row affected (0.00 sec)

-- 查看數(shù)據(jù)
SELECT * FROM for_delete;
+----+------+
| id | name |
+----+------+
|  4 | D    |
+----+------+
1 row in set (0.00 sec)

-- 查看表結(jié)構(gòu),會有 AUTO_INCREMENT=n 項
SHOW CREATE TABLE for_delete\G
*************************** 1. row ***************************
       Table: for_delete
Create Table: CREATE TABLE `for_delete` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
1 row in set
### 5.2 ?? 截斷表(TRUNCATE)

**語法:**

```sql
TRUNCATE [TABLE] table_name

注意:這個操作慎用!

  1. 只能對整表操作,不能像 DELETE 一樣針對部分?jǐn)?shù)據(jù)操作;
  2. 實際上 MySQL 不對數(shù)據(jù)操作,所以比 DELETE 更快,但是 TRUNCATE 在刪除數(shù)據(jù)的時候,并不經(jīng)過真正的事務(wù),所以無法回滾;
  3. 會重置 AUTO_INCREMENT 項。
-- 準(zhǔn)備測試表
CREATE TABLE for_truncate (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20)
);
Query OK, 0 rows affected (0.16 sec)

-- 插入測試數(shù)據(jù)
INSERT INTO for_truncate (name) VALUES ('A'), ('B'), ('C');
Query OK, 3 rows affected (1.05 sec)
Records: 3  Duplicates: 0  Warnings: 0

-- 查看測試數(shù)據(jù)
SELECT * FROM for_truncate;
+----+------+
| id | name |
+----+------+
|  1 | A    |
|  2 | B    |
|  3 | C    |
+----+------+
3 rows in set (0.00 sec)

-- 截斷整表數(shù)據(jù)
TRUNCATE for_truncate;
Query OK, 0 rows affected (0.19 sec)

-- 查看截斷結(jié)果
SELECT * FROM for_truncate;
Empty set (0.00 sec)

-- 再插入一條數(shù)據(jù),自增 id 從 1 開始
INSERT INTO for_truncate (name) VALUES ('D');
Query OK, 1 row affected (0.00 sec)

-- 查看數(shù)據(jù),id 從 1 重新開始
SELECT * FROM for_truncate;
+----+------+
| id | name |
+----+------+
|  1 | D    |
+----+------+
1 row in set (0.00 sec)

-- 查看表結(jié)構(gòu),AUTO_INCREMENT 已重置為 1
SHOW CREATE TABLE for_truncate\G
*************************** 1. row ***************************
       Table: for_truncate
Create Table: CREATE TABLE `for_truncate` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

DELETE vs TRUNCATE 對比

對比項DELETETRUNCATE
條件刪除? 支持 WHERE 條件? 只能整表刪除
事務(wù)支持? 支持事務(wù),可回滾? 不經(jīng)過事務(wù),無法回滾
速度慢(逐行刪除)快(直接釋放數(shù)據(jù)頁)
AUTO_INCREMENT不會重置會重置
觸發(fā)器會觸發(fā) DELETE 觸發(fā)器不會觸發(fā)觸發(fā)器
DML/DCLDML(數(shù)據(jù)操作語言)DDL(數(shù)據(jù)定義語言)

6. 插入查詢結(jié)果(INSERT INTO SELECT)

6.1 語法

INSERT INTO table_name [(column [, column ...])] SELECT ...

將查詢結(jié)果插入到目標(biāo)表中,查詢的列數(shù)、類型必須與目標(biāo)表匹配。

6.2 案例實操

案例:刪除表中的重復(fù)記錄,重復(fù)的數(shù)據(jù)只能有一份

-- 創(chuàng)建一張有重復(fù)數(shù)據(jù)的表
CREATE TABLE duplicate_data (
    id INT,
    name VARCHAR(20)
);

-- 插入測試數(shù)據(jù)(包含重復(fù)記錄)
INSERT INTO duplicate_data VALUES
    (1, '唐三藏'),
    (2, '孫悟空'),
    (3, '豬悟能'),
    (1, '唐三藏'),   -- 重復(fù)
    (2, '孫悟空');   -- 重復(fù)
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

-- 查看原數(shù)據(jù)
SELECT * FROM duplicate_data;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | 唐三藏    |
|    2 | 孫悟空    |
|    3 | 豬悟能    |
|    1 | 唐三藏    |
|    2 | 孫悟空    |
+------+-----------+
5 rows in set (0.00 sec)

-- 第一步:創(chuàng)建一張結(jié)構(gòu)相同的臨時表
CREATE TABLE duplicate_tmp LIKE duplicate_data;
Query OK, 0 rows affected (0.13 sec)

-- 第二步:將去重后的數(shù)據(jù)插入臨時表
INSERT INTO duplicate_tmp SELECT DISTINCT * FROM duplicate_data;
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

-- 查看臨時表數(shù)據(jù)
SELECT * FROM duplicate_tmp;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | 唐三藏    |
|    2 | 孫悟空    |
|    3 | 豬悟能    |
+------+-----------+
3 rows in set (0.00 sec)

-- 第三步:刪除原表
DROP TABLE duplicate_data;
Query OK, 0 rows affected (0.05 sec)

-- 第四步:將臨時表重命名為原表名
RENAME TABLE duplicate_tmp TO duplicate_data;
Query OK, 0 rows affected (0.05 sec)

-- 查看最終結(jié)果
SELECT * FROM duplicate_data;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | 唐三藏    |
|    2 | 孫悟空    |
|    3 | 豬悟能    |
+------+-----------+
3 rows in set (0.00 sec)

7. 聚合函數(shù)

7.1 常用聚合函數(shù)

函數(shù)說明
COUNT([DISTINCT] expr)返回查詢到的數(shù)據(jù)的 數(shù)量
SUM([DISTINCT] expr)返回查詢到的數(shù)據(jù)的 總和,不是數(shù)字沒有意義
AVG([DISTINCT] expr)返回查詢到的數(shù)據(jù)的 平均值,不是數(shù)字沒有意義
MAX([DISTINCT] expr)返回查詢到的數(shù)據(jù)的 最大值,不是數(shù)字沒有意義
MIN([DISTINCT] expr)返回查詢到的數(shù)據(jù)的 最小值,不是數(shù)字沒有意義

7.2 案例實操

以下案例基于 exam_result 表(已恢復(fù)原始數(shù)據(jù))。

7.2.1 統(tǒng)計班級共有多少同學(xué)

-- 使用 * 做統(tǒng)計,不受 NULL 影響
SELECT COUNT(*) FROM exam_result;
+----------+
| COUNT(*) |
+----------+
|        7 |
+----------+
1 row in set (0.00 sec)

-- 使用表達(dá)式,不受 NULL 影響
SELECT COUNT(1) FROM exam_result;
+----------+
| COUNT(1) |
+----------+
|        7 |
+----------+
1 row in set (0.00 sec)

小知識COUNT(*)COUNT(1) 在 InnoDB 引擎下性能幾乎一致,沒有本質(zhì)區(qū)別。

7.2.2 統(tǒng)計班級收集的 qq 號有多少

-- COUNT(具體列) 會忽略 NULL 值
SELECT COUNT(qq) FROM students;
+-----------+
| COUNT(qq) |
+-----------+
|         1 |
+-----------+
1 row in set (0.00 sec)

7.2.3 統(tǒng)計本次考試的數(shù)學(xué)成績分?jǐn)?shù)個數(shù)

-- COUNT(distinct 列) 會去重
SELECT COUNT(DISTINCT math) FROM exam_result;
+---------------------+
| COUNT(DISTINCT math)|
+---------------------+
|                   6 |
+---------------------+
1 row in set (0.00 sec)

7.2.4 統(tǒng)計數(shù)學(xué)成績總分

SELECT SUM(math) FROM exam_result;
+-----------+
| SUM(math) |
+-----------+
|       581 |
+-----------+
1 row in set (0.00 sec)

7.2.5 統(tǒng)計數(shù)學(xué)成績平均分

SELECT AVG(math) FROM exam_result;
+-----------+
| AVG(math) |
+-----------+
|   83.0000 |
+-----------+
1 row in set (0.00 sec)

7.2.6 統(tǒng)計英語成績最高分

SELECT MAX(english) FROM exam_result;
+--------------+
| MAX(english) |
+--------------+
|           90 |
+--------------+
1 row in set (0.00 sec)

7.2.7 統(tǒng)計英語成績最低分

SELECT MIN(english) FROM exam_result;
+--------------+
| MIN(english) |
+--------------+
|           30 |
+--------------+
1 row in set (0.00 sec)

7.2.8 統(tǒng)計英語成績總分、平均分、最高分、最低分

SELECT
    SUM(english)  英語總分,
    AVG(english)  英語平均分,
    MAX(english)  英語最高分,
    MIN(english)  英語最低分
FROM exam_result;
+-----------+--------------+--------------+--------------+
| 英語總分  | 英語平均分   | 英語最高分   | 英語最低分   |
+-----------+--------------+--------------+--------------+
|       443 |      63.2857 |           90 |           30 |
+-----------+--------------+--------------+--------------+
1 row in set (0.00 sec)

8. GROUP BY 子句

8.1 語法

解釋:

1.在select中使用group by 子句可以對指定列進(jìn)行分組查詢

2.先對一列中的不同數(shù)據(jù)進(jìn)行分組,再進(jìn)行聚合統(tǒng)計。

3.分組的目的是為了進(jìn)行分組之后,方便進(jìn)行聚合統(tǒng)計。

SELECT column, aggregate_function(column)
FROM table_name
[WHERE ...]
GROUP BY column
[HAVING ...]
[ORDER BY ...]
[LIMIT ...]

執(zhí)行順序FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT

執(zhí)行順序理解:

1.來之哪個表

2.where條件篩選

3.group by 分組

4.執(zhí)行聚合

5.執(zhí)行having進(jìn)行條件篩選

注解:

1.指定列名,實際分組,使用該列的不同行數(shù)據(jù)來進(jìn)行分組的分組的條件deptno,組內(nèi)一定是相同的 可以被聚合壓縮分組,不就是把一組按照條件拆成了多少個組,進(jìn)行各自組內(nèi)的統(tǒng)計

2.分組(分表),不就是把一張表按照條件在邏輯上拆成了多個子表,然后分別對各自的子表進(jìn)行聚合統(tǒng)計。

注意:

1.只有在group by 后面的列才能出現(xiàn)在select后面

2.group by 后面可以跟多個列來進(jìn)行分組。

8.2 案例實操

準(zhǔn)備雇員信息表(emp)、部門表(dept)、薪資等級表(salgrade)。

-- 創(chuàng)建部門表
CREATE TABLE dept (
    deptno INT PRIMARY KEY,
    dname VARCHAR(20) COMMENT '部門名稱',
    loc VARCHAR(20) COMMENT '部門所在地'
);

-- 插入部門數(shù)據(jù)
INSERT INTO dept VALUES
    (10, '教研部', '北京'),
    (20, '學(xué)工部', '上海'),
    (30, '銷售部', '廣州'),
    (40, '財務(wù)部', '深圳');

-- 創(chuàng)建薪資等級表
CREATE TABLE salgrade (
    grade INT PRIMARY KEY COMMENT '薪資等級',
    losal INT COMMENT '最低薪資',
    hisal INT COMMENT '最高薪資'
);

-- 插入薪資等級數(shù)據(jù)
INSERT INTO salgrade VALUES
    (1, 700, 1200),
    (2, 1201, 1400),
    (3, 1401, 2000),
    (4, 2001, 3000),
    (5, 3001, 9999);

-- 創(chuàng)建雇員表
CREATE TABLE emp (
    empno INT PRIMARY KEY COMMENT '雇員編號',
    ename VARCHAR(20) COMMENT '雇員姓名',
    job VARCHAR(20) COMMENT '雇員職位',
    mgr INT COMMENT '雇員上級編號',
    hiredate DATE COMMENT '雇傭日期',
    sal INT COMMENT '薪資',
    comm INT COMMENT '獎金',
    deptno INT COMMENT '部門編號'
);

-- 插入雇員數(shù)據(jù)
INSERT INTO emp VALUES
    (1001, '孫悟空', '講師', 1004, '2000-12-17', 8000, NULL, 10),
    (1002, '豬悟能', '學(xué)工主任', 1009, '2001-02-20', 16000, 3000, 20),
    (1003, '沙悟凈', '咨詢師', 1004, '2001-02-22', 12500, 5000, 30),
    (1004, '唐三藏', '教研主任', 1009, '2001-04-02', 29750, NULL, 10),
    (1005, '劉玄德', '銷售員', 1006, '2001-09-28', 12500, 14000, 30),
    (1006, '曹孟德', '銷售經(jīng)理', 1009, '2001-05-01', 28500, NULL, 30),
    (1007, '孫仲謀', '分析師', 1004, '2001-09-01', 24500, NULL, 10),
    (1008, '宋公明', '講師', 1004, '2001-04-12', 15000, NULL, 10),
    (1009, '劉邦', '總裁', NULL, '2001-11-17', 50000, NULL, 20),
    (1010, '韓信', '銷售員', 1006, '2001-09-08', 15000, 0, 30),
    (1011, '周公瑾', '分析師', 1004, '2007-01-12', 21000, NULL, 10);

8.2.1 顯示每個部門的平均工資和最高工資

SELECT
    deptno,
    AVG(sal) 平均工資,
    MAX(sal) 最高工資
FROM emp
GROUP BY deptno;
+--------+--------------+--------------+
| deptno | 平均工資     | 最高工資     |
+--------+--------------+--------------+
|     10 | 19550.0000   |        29750 |
|     20 | 33000.0000   |        50000 |
|     30 | 16375.0000   |        28500 |
+--------+--------------+--------------+
3 rows in set (0.00 sec)

8.2.2 顯示每個部門的每種崗位的平均工資和最低工資

SELECT
    deptno,
    job,
    AVG(sal) 平均工資,
    MIN(sal) 最低工資
FROM emp
GROUP BY deptno, job;
+--------+--------------+--------------+--------------+
| deptno | job          | 平均工資     | 最低工資     |
+--------+--------------+--------------+--------------+
|     10 | 分析師       | 22750.0000   |        21000 |
|     10 | 教研主任     | 29750.0000   |        29750 |
|     10 | 講師         | 11500.0000   |         8000 |
|     20 | 學(xué)工主任     | 16000.0000   |        16000 |
|     20 | 總裁         | 50000.0000   |        50000 |
|     30 | 銷售經(jīng)理     | 28500.0000   |        28500 |
|     30 | 銷售員       | 13333.3333   |        12500 |
|     30 | 咨詢師       | 12500.0000   |        12500 |
+--------+--------------+--------------+--------------+
8 rows in set (0.00 sec)

8.2.3 顯示平均工資低于 20000 的部門及其平均工資

-- HAVING 用于對分組后的結(jié)果進(jìn)行過濾
SELECT
    deptno,
    AVG(sal) 平均工資
FROM emp
GROUP BY deptno
HAVING 平均工資 < 20000;
+--------+--------------+
| deptno | 平均工資     |
+--------+--------------+
|     10 | 19550.0000   |
|     30 | 16375.0000   |
+--------+--------------+
2 rows in set (0.00 sec)
--having經(jīng)常和group by搭配使用,作用是對分組進(jìn)行篩選,作用有些像where

WHERE vs HAVING 區(qū)別

  • WHERE:在 分組之前 過濾數(shù)據(jù),不能使用聚合函數(shù)
  • HAVING:在 分組之后 過濾數(shù)據(jù),可以使用聚合函數(shù)

小總結(jié):

1.不要單純的認(rèn)為,只有磁盤上表結(jié)構(gòu)導(dǎo)入到mysql,真實存在的表才叫表之間篩選出來的,包括最終的結(jié)果,在我看來,全部都是邏輯上的表!即 “MySQL一切皆是表”

2.未來只要我們能夠處理好單表的CURD,所有的sql場景,我們?nèi)慷寄苡媒y(tǒng)一的方式執(zhí)行。

9. 實戰(zhàn) OJ 練習(xí)

以下題目來自??途W(wǎng)、LeetCode 等平臺,幫助你鞏固 CRUD 知識。

9.1 查找最晚入職員工的所有信息

-- 方法一:使用 ORDER BY + LIMIT
SELECT * FROM employees
ORDER BY hire_date DESC
LIMIT 1;

-- 方法二:使用子查詢
SELECT * FROM employees
WHERE hire_date = (SELECT MAX(hire_date) FROM employees);

9.2 查找入職員工時間排名倒數(shù)第三的員工信息

-- 使用 ORDER BY + LIMIT OFFSET
SELECT * FROM employees
ORDER BY hire_date DESC
LIMIT 1 OFFSET 2;

9.3 查找當(dāng)前薪水詳情以及部門編號 dept_no

SELECT
    s.*,
    d.dept_no
FROM salaries s
JOIN dept_emp d ON s.emp_no = d.emp_no
WHERE s.to_date = '9999-01-01'
  AND d.to_date = '9999-01-01';

9.4 查找所有已經(jīng)分配部門的員工的姓名和部門號

SELECT
    e.last_name,
    e.first_name,
    d.dept_no
FROM employees e
JOIN dept_emp d ON e.emp_no = d.emp_no;

9.5 查找所有員工的姓名以及其部門號(包含未分配部門的員工)

SELECT
    e.last_name,
    e.first_name,
    d.dept_no
FROM employees e
LEFT JOIN dept_emp d ON e.emp_no = d.emp_no;

10. 總結(jié)與面試題

10.1 知識總結(jié)

操作關(guān)鍵字要點
創(chuàng)建INSERT支持單行/多行插入,ON DUPLICATE KEY UPDATE 處理沖突
讀取SELECT支持條件篩選(WHERE)、排序(ORDER BY)、分頁(LIMIT
更新UPDATE配合 WHERE 限定范圍,支持表達(dá)式運(yùn)算
刪除DELETE / TRUNCATEDELETE 可條件刪除,TRUNCATE 清空整表并重置自增
聚合COUNT / SUM / AVG / MAX / MIN常與 GROUP BY 配合使用
分組GROUP BY / HAVINGHAVING 過濾分組結(jié)果,可使用聚合函數(shù)

10.2 經(jīng)典面試題

Q1:WHEREHAVING 的區(qū)別?

A:

  • WHERE 在分組前過濾行,不能使用聚合函數(shù)
  • HAVING 在分組后過濾組,可以使用聚合函數(shù)
  • 執(zhí)行順序:WHEREGROUP BYHAVING

Q2:DELETETRUNCATE 的區(qū)別?

A:

  • DELETE 是 DML,支持事務(wù)可回滾,可加 WHERE 條件,不重置自增
  • TRUNCATE 是 DDL,不支持事務(wù)不可回滾,只能整表刪除,重置自增

Q3:COUNT(*)、COUNT(1)、COUNT(列名) 的區(qū)別?

A:

  • COUNT(*) 統(tǒng)計所有行數(shù),包含 NULL
  • COUNT(1)COUNT(*) 效果相同,InnoDB 下性能一致
  • COUNT(列名) 統(tǒng)計該列非 NULL 的行數(shù)

Q4:SQL 語句的執(zhí)行順序是怎樣的?

A:

FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT

Q5:ON DUPLICATE KEY UPDATEREPLACE 的區(qū)別?

A:

  • ON DUPLICATE KEY UPDATE:沖突時執(zhí)行 UPDATE,不刪除原記錄
  • REPLACE:沖突時先 DELETE 再 INSERT,可能導(dǎo)致自增 id 變化

恭喜你! 你已經(jīng)完整掌握了 MySQL 的 CRUD 操作。從基礎(chǔ)的增刪改查到高級的聚合分組、去重分頁,再到實戰(zhàn) OJ 練習(xí),相信你已經(jīng)具備了扎實的 SQL 基礎(chǔ)。繼續(xù)加油,向更高級的 SQL 優(yōu)化、索引、事務(wù)等知識進(jìn)發(fā)吧!

以上就是MySQL核心必會之表的增刪改查(CRUD)實戰(zhàn)指南的詳細(xì)內(nèi)容,更多關(guān)于MySQL表增刪改查的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MySQL數(shù)字的取整、四舍五入、保留n位小數(shù)方式

    MySQL數(shù)字的取整、四舍五入、保留n位小數(shù)方式

    這篇文章主要介紹了MySQL數(shù)字的取整、四舍五入、保留n位小數(shù)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • mysql 8.0.14 安裝配置方法圖文教程(通用)

    mysql 8.0.14 安裝配置方法圖文教程(通用)

    這篇文章主要為大家詳細(xì)介紹了mysql 8.0.14 安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • MySQL中的集合運(yùn)算符詳解

    MySQL中的集合運(yùn)算符詳解

    本文主要介紹了MySQL中的集合運(yùn)算符,包括UNION、INTERSECT、EXCEPT等,這些運(yùn)算符用于結(jié)合兩個或多個SELECT語句的結(jié)果集,并進(jìn)行去重、合并或差集操作
    2025-02-02
  • MySQL記錄操作日志常用的幾種實現(xiàn)方法

    MySQL記錄操作日志常用的幾種實現(xiàn)方法

    這篇文章主要介紹了MySQL記錄操作日志常用的幾種實現(xiàn)方法,文中介紹的方法包括啟用通用查詢?nèi)罩?、二進(jìn)制日志、使用審計插件和觸發(fā)器,每種方法都有其適用場景和優(yōu)缺點,選擇合適的方法可以有效跟蹤和管理數(shù)據(jù)庫操作,需要的朋友可以參考下
    2024-11-11
  • MySQL REVOKE實現(xiàn)刪除用戶權(quán)限

    MySQL REVOKE實現(xiàn)刪除用戶權(quán)限

    在 MySQL 中,可以使用 REVOKE 語句刪除某個用戶的某些權(quán)限,本文就詳細(xì)的來介紹一下REVOKE 的具體使用方法,感興趣的可以了解一下
    2021-06-06
  • mysql 5.7.21 安裝配置方法圖文教程(window)

    mysql 5.7.21 安裝配置方法圖文教程(window)

    這篇文章主要為大家詳細(xì)介紹了window環(huán)境下mysql5.7.21安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • navicat連接mysql出現(xiàn)2059錯誤的解決方法

    navicat連接mysql出現(xiàn)2059錯誤的解決方法

    這篇文章主要為大家詳細(xì)介紹了navicat連接mysql出現(xiàn)2059錯誤的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • 淺析MySQL 備份與恢復(fù)

    淺析MySQL 備份與恢復(fù)

    這篇文章主要介紹了MySQL 備份與恢復(fù)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)MySQL,感興趣的朋友可以了解下
    2020-08-08
  • MySQL存儲過程的優(yōu)化實例

    MySQL存儲過程的優(yōu)化實例

    在編寫MySQL存儲過程的過程中,我們會時不時地需要對某些存儲過程進(jìn)行優(yōu)化,其目的是確保代碼的可讀性、正確性及運(yùn)行性能。本文以作者實際工作為背景,介紹了對某一個MySQL存儲過程優(yōu)化的整個過程。
    2016-07-07
  • 5個保護(hù)MySQL數(shù)據(jù)倉庫的小技巧

    5個保護(hù)MySQL數(shù)據(jù)倉庫的小技巧

    這篇文章主要為大家詳細(xì)介紹了五個小技巧,告訴你如何保護(hù)MySQL數(shù)據(jù)倉庫,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08

最新評論

南京市| 汨罗市| 棋牌| 什邡市| 吴川市| 佛冈县| 慈溪市| 安泽县| 兰西县| 商河县| 新蔡县| 漳州市| 溧阳市| 浪卡子县| 永丰县| 洛宁县| 繁昌县| 晋江市| 唐海县| 治县。| 增城市| 恩施市| 利辛县| 云浮市| 衡东县| 桑日县| 龙门县| 杭锦后旗| 漯河市| 奈曼旗| 内江市| 神农架林区| 辰溪县| 宁河县| 阿合奇县| 浪卡子县| 兖州市| 普兰县| 青川县| 普兰县| 涟源市|