MySQL表的增刪改查(CRUD)
文章目錄
- MySQL表的增刪改查(CRUD)
- 1. Create
- 1.1 單行數據 + 全列插入
- 1.2 多行數據 + 指定列插入
- 1.3 插入否則更新
- 1.4 替換
- 2. Retrieve
- 2.1 SELECT 列
- 2.1.1 全列查詢
- 2.1.2 指定列查詢
- 2.1.3 查詢字段為表達式
- 2.1.4 為查詢指定別名
- 2.1.5 結果去重
- 2.2 WHERE 條件
- 2.2.1 英語不及格的同學(英語成績<60)及英語成績
- 2.2.2 語文成績在 [80, 90] 分的同學及語文成績
- 2.2.3 數學成績是 58 或者 59 或者 98 或者 99 分的同學及數學成績
- 2.2.4 姓孫的同學 及 孫某同學
- 2.2.5 語文成績好于英語成績的同學
- 2.2.6 總分在 200 分以下的同學
- 2.2.7 語文成績 > 80 并且不姓孫的同學
- 2.2.8 孫某同學,否則要求總成績 > 200 并且 語文成績 < 數學成績 并且 英語成績 > 80
- 2.2.9 NULL 的查詢
- 2.3 結果排序
- 2.3.1 同學及數學成績,按數學成績升序顯示
- 2.3.2 同學及 qq 號,按 qq 號排序顯示
- 2.3.3 查詢同學各門成績,依次按 數學降序,英語升序,語文升序的方式顯示
- 2.3.4 查詢同學及總分,由高到低
- 2.3.5 查詢姓孫的同學或者姓曹的同學數學成績,結果按數學成績由高到低顯示
- 2.4 篩選分頁結果
- 3. Update
- 3.1 單列變更
- 3.2 一次更新多個列
- 3.3 更新值為原值基礎上進行變更
- 3.4 將所有同學的語文成績更新為原來的 2 倍
- 4. Delete
- 4.1 刪除數據
- 4.1.1 刪除孫悟空同學的考試成績
- 4.1.2 刪除整張表數據
- 4.2 截斷表
- 5. 插入查詢結果(insert into... select...)
- 6. 聚合函數
- 6.1 統計班級共有多少同學
- 6.2 統計班級收集的 qq 號有多少
- 6.3 統計本次考試的數學成績分數個數
- 6.4 統計數學成績總分
- 6.5 統計平均總分
- 6.6 返回英語最高分
- 6.7 返回 > 70 分以上的數學最低分
- 7. group by子句的使用
SQL查詢中各個關鍵字的執行先后順序
from > on > join > where > group by > with > having > select > distinct > order by > limit
1. Create
語法:
INSERT [INTO] table_name
[(column [, column] ...)]
VALUES (value_list) [, (value_list)] ...
value_list: value, [, value] ...
案例:
# 創建一張學生表
CREATE TABLE students (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
sn INT NOT NULL UNIQUE COMMENT '學號',
name VARCHAR(20) NOT NULL,
qq VARCHAR(20)
);
1.1 單行數據 + 全列插入
插入兩條記錄,value_list 數量必須和定義表的列的數量及順序一致。
mysql> INSERT INTO students VALUES (100, 10000, '唐三藏', NULL);
Query OK, 1 row affected (0.00 sec)mysql> INSERT INTO students VALUES (101, 10001, '孫悟空', '11111');
Query OK, 1 row affected (0.01 sec)mysql> SELECT * FROM students;
+-----+-------+-----------+-------+
| id | sn | name | qq |
+-----+-------+-----------+-------+
| 100 | 10000 | 唐三藏 | NULL |
| 101 | 10001 | 孫悟空 | 11111 |
+-----+-------+-----------+-------+
2 rows in set (0.00 sec)
注意,這里在插入的時候,也可以不用指定id(當然,那時候就需要明確插入數據到那些列了),那么mysql會使用默認的值進行自增。
1.2 多行數據 + 指定列插入
插入兩條記錄,value_list 數量必須和指定列數量及順序一致
mysql> INSERT INTO students (id, sn, name) VALUES-> (102, 20001, '曹孟德'),-> (103, 20002, '孫仲謀');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0mysql> 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)
1.3 插入否則更新
由于 主鍵 或者 唯一鍵 對應的值已經存在而導致插入失敗
# 主鍵沖突
mysql> INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大師');
ERROR 1062 (23000): Duplicate entry '100' for key 'students.PRIMARY'
# 唯一鍵沖突
mysql> INSERT INTO students (sn, name) VALUES (20001, '曹阿瞞');
ERROR 1062 (23000): Duplicate entry '20001' for key 'students.sn'
可以選擇性的進行同步更新操作
語法:
INSERT ... ON DUPLICATE KEY UPDATE
column = value [, column = value] ...
ON DUPLICATE KEY
當發生重復key的時候
示例:
mysql> INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大師')
ON DUPLICATE KEY UPDATE sn = 10010, name = '唐大師';
Query OK, 2 rows affected (0.47 sec)
-- 0 row affected: 表中有沖突數據,但沖突數據的值和 update 的值相等
-- 1 row affected: 表中沒有沖突數據,數據被插入
-- 2 row affected: 表中有沖突數據,并且數據已經被更新mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
| -1 |
+-------------+
1 row in set (0.00 sec)
1.4 替換
# 主鍵 或者 唯一鍵 沒有沖突,則直接插入;
# 主鍵 或者 唯一鍵 如果沖突,則刪除后再插入REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞞');
Query OK, 2 rows affected (0.00 sec)
-- 1 row affected: 表中沒有沖突數據,數據被插入
-- 2 row affected: 表中有沖突數據,刪除后重新插入
2. Retrieve
語法:
SELECT
[DISTINCT] {* | {column [, column] ...}
[FROM table_name]
[WHERE ...]
[ORDER BY column [ASC | DESC], ...]
LIMIT ...
案例前置數據導入:
mysql> CREATE TABLE exam_result (-> id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,-> name VARCHAR(20) NOT NULL COMMENT '同學姓名',-> chinese float DEFAULT 0.0 COMMENT '語文成績',-> math float DEFAULT 0.0 COMMENT '數學成績',-> english float DEFAULT 0.0 COMMENT '英語成績'-> );
Query OK, 0 rows affected (0.02 sec)mysql> INSERT INTO exam_result (name, chinese, math, english) VALUES-> ('唐三藏', 67, 98, 56),-> ('孫悟空', 87, 78, 77),-> ('豬悟能', 88, 98, 90),-> ('曹孟德', 82, 84, 67),-> ('劉玄德', 55, 85, 45),-> ('孫權', 70, 73, 78),-> ('宋公明', 75, 65, 30);
Query OK, 7 rows affected (0.01 sec)
Records: 7 Duplicates: 0 Warnings: 0
2.1 SELECT 列
2.1.1 全列查詢
語法:
SELECT * FROM 表名;
通常情況下不建議使用 * 進行全列查詢
-
查詢的列越多,意味著需要傳輸的數據量越大;
-
可能會影響到索引的使用。
案例:
mysql> 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 | 孫權 | 70 | 73 | 78 |
| 7 | 宋公明 | 75 | 65 | 30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)
2.1.2 指定列查詢
指定列的順序不需要按定義表的順序
mysql> SELECT id, name, english FROM exam_result;
+----+-----------+---------+
| id | name | english |
+----+-----------+---------+
| 1 | 唐三藏 | 56 |
| 2 | 孫悟空 | 77 |
| 3 | 豬悟能 | 90 |
| 4 | 曹孟德 | 67 |
| 5 | 劉玄德 | 45 |
| 6 | 孫權 | 78 |
| 7 | 宋公明 | 30 |
+----+-----------+---------+
7 rows in set (0.00 sec)mysql> SELECT id, math, name FROM exam_result;
+----+------+-----------+
| id | math | name |
+----+------+-----------+
| 1 | 98 | 唐三藏 |
| 2 | 78 | 孫悟空 |
| 3 | 98 | 豬悟能 |
| 4 | 84 | 曹孟德 |
| 5 | 85 | 劉玄德 |
| 6 | 73 | 孫權 |
| 7 | 65 | 宋公明 |
+----+------+-----------+
7 rows in set (0.00 sec)
2.1.3 查詢字段為表達式
- 表達式不包含字段
mysql> SELECT id, name, 10 FROM exam_result;
+----+-----------+----+
| id | name | 10 |
+----+-----------+----+
| 1 | 唐三藏 | 10 |
| 2 | 孫悟空 | 10 |
| 3 | 豬悟能 | 10 |
| 4 | 曹孟德 | 10 |
| 5 | 劉玄德 | 10 |
| 6 | 孫權 | 10 |
| 7 | 宋公明 | 10 |
+----+-----------+----+
7 rows in set (0.01 sec)
- 表達式包含一個字段
mysql> SELECT id, name, english + 10 FROM exam_result;
+----+-----------+--------------+
| id | name | english + 10 |
+----+-----------+--------------+
| 1 | 唐三藏 | 66 |
| 2 | 孫悟空 | 87 |
| 3 | 豬悟能 | 100 |
| 4 | 曹孟德 | 77 |
| 5 | 劉玄德 | 55 |
| 6 | 孫權 | 88 |
| 7 | 宋公明 | 40 |
+----+-----------+--------------+
7 rows in set (0.01 sec)
- 表達式包含多個字段
mysql> 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 | 孫權 | 221 |
| 7 | 宋公明 | 170 |
+----+-----------+--------------------------+
7 rows in set (0.01 sec)
2.1.4 為查詢指定別名
語法:
SELECT column [AS] alias_name [...] FROM table_name;
案例:
mysql> SELECT id, name, chinese + math + english 總分 FROM exam_result;
+----+-----------+--------+
| id | name | 總分 |
+----+-----------+--------+
| 1 | 唐三藏 | 221 |
| 2 | 孫悟空 | 242 |
| 3 | 豬悟能 | 276 |
| 4 | 曹孟德 | 233 |
| 5 | 劉玄德 | 185 |
| 6 | 孫權 | 221 |
| 7 | 宋公明 | 170 |
+----+-----------+--------+
7 rows in set (0.00 sec)
2.1.5 結果去重
# 查詢發現數學成績有重復的
mysql> SELECT math FROM exam_result;
+------+
| math |
+------+
| 98 |
| 78 |
| 98 |
| 84 |
| 85 |
| 73 |
| 65 |
+------+
7 rows in set (0.00 sec)# 利用DISTINCT關鍵字去重
mysql> SELECT DISTINCT math FROM exam_result;
+------+
| math |
+------+
| 98 |
| 78 |
| 84 |
| 85 |
| 73 |
| 65 |
+------+
6 rows in set (0.03 sec)
2.2 WHERE 條件
比較運算符:
邏輯運算符:
案例:
2.2.1 英語不及格的同學(英語成績<60)及英語成績
mysql> SELECT name, english FROM exam_result WHERE english < 60;
+-----------+---------+
| name | english |
+-----------+---------+
| 唐三藏 | 56 |
| 劉玄德 | 45 |
| 宋公明 | 30 |
+-----------+---------+
3 rows in set (0.01 sec)
2.2.2 語文成績在 [80, 90] 分的同學及語文成績
# 使用 and 條件連接語句
mysql> 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... 語句
mysql> SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;
+-----------+---------+
| name | chinese |
+-----------+---------+
| 孫悟空 | 87 |
| 豬悟能 | 88 |
| 曹孟德 | 82 |
+-----------+---------+
3 rows in set (0.02 sec)
2.2.3 數學成績是 58 或者 59 或者 98 或者 99 分的同學及數學成績
# 使用 or 條件連接語句
mysql> 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.00 sec)# 使用 in 語句
mysql> SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);
+-----------+------+
| name | math |
+-----------+------+
| 唐三藏 | 98 |
| 豬悟能 | 98 |
+-----------+------+
2 rows in set (0.00 sec)
2.2.4 姓孫的同學 及 孫某同學
- % 匹配任意多個(包括 0 個)任意字符
mysql> SELECT name FROM exam_result WHERE name LIKE '孫%';
+-----------+
| name |
+-----------+
| 孫悟空 |
| 孫權 |
+-----------+
2 rows in set (0.01 sec)
- _ 匹配嚴格的一個任意字符
mysql> SELECT name FROM exam_result WHERE name LIKE '孫_';
+--------+
| name |
+--------+
| 孫權 |
+--------+
1 row in set (0.00 sec)
2.2.5 語文成績好于英語成績的同學
WHERE 條件中比較運算符兩側都是字段
mysql> 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)
2.2.6 總分在 200 分以下的同學
WHERE 條件中使用表達式
# 別名不能用在 WHERE 條件中
mysql> SELECT name, chinese + math + english 總分 FROM exam_result-> WHERE chinese + math + english < 200;
+-----------+--------+
| name | 總分 |
+-----------+--------+
| 劉玄德 | 185 |
| 宋公明 | 170 |
+-----------+--------+
2 rows in set (0.00 sec)
2.2.7 語文成績 > 80 并且不姓孫的同學
# and 與 not 的使用
mysql> SELECT name, chinese FROM exam_result-> WHERE chinese > 80 AND name NOT LIKE '孫%';
+-----------+---------+
| name | chinese |
+-----------+---------+
| 豬悟能 | 88 |
| 曹孟德 | 82 |
+-----------+---------+
2 rows in set (0.00 sec)
2.2.8 孫某同學,否則要求總成績 > 200 并且 語文成績 < 數學成績 并且 英語成績 > 80
# 綜合查詢
mysql> select name, chinese, math, english, chinese+math+english total-> from exam_result where-> (name like '孫%') or-> (chinese+math+english > 200 and chinese < math and english > 80);
+-----------+---------+------+---------+-------+
| name | chinese | math | english | total |
+-----------+---------+------+---------+-------+
| 孫悟空 | 87 | 78 | 77 | 242 |
| 豬悟能 | 88 | 98 | 90 | 276 |
| 孫權 | 70 | 73 | 78 | 221 |
+-----------+---------+------+---------+-------+
3 rows in set (0.00 sec)
2.2.9 NULL 的查詢
# 查詢所有學生
mysql> select * from students;
+-----+-------+-----------+-------+
| id | sn | name | qq |
+-----+-------+-----------+-------+
| 100 | 10010 | 唐大師 | NULL |
| 101 | 10001 | 孫悟空 | 11111 |
| 103 | 20002 | 孫仲謀 | NULL |
| 105 | 20001 | 曹阿瞞 | NULL |
+-----+-------+-----------+-------+
4 rows in set (0.01 sec)# 查詢 qq 非空的學生
mysql> SELECT name, qq FROM students WHERE qq IS NOT NULL;
+-----------+-------+
| name | qq |
+-----------+-------+
| 孫悟空 | 11111 |
+-----------+-------+
1 row in set (0.00 sec)# = 和 <=> 對NULL查詢的影響
mysql> SELECT NULL = NULL, NULL = 1, NULL = 0;
+-------------+----------+----------+
| NULL = NULL | NULL = 1 | NULL = 0 |
+-------------+----------+----------+
| NULL | NULL | NULL |
+-------------+----------+----------+
1 row in set (0.00 sec)mysql> SELECT NULL <=> NULL, NULL <=> 1, NULL <=> 0;
+---------------+------------+------------+
| NULL <=> NULL | NULL <=> 1 | NULL <=> 0 |
+---------------+------------+------------+
| 1 | 0 | 0 |
+---------------+------------+------------+
1 row in set (0.00 sec)
2.3 結果排序
- ASC 為升序(從小到大)
- DESC 為降序(從大到小)
- 默認為 ASC
語法:
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...];
注意:沒有 ORDER BY 子句的查詢,返回的順序是未定義的,永遠不要依賴這個順序
案例:
2.3.1 同學及數學成績,按數學成績升序顯示
mysql> SELECT name, math FROM exam_result ORDER BY math;
+-----------+------+
| name | math |
+-----------+------+
| 宋公明 | 65 |
| 孫權 | 73 |
| 孫悟空 | 78 |
| 曹孟德 | 84 |
| 劉玄德 | 85 |
| 唐三藏 | 98 |
| 豬悟能 | 98 |
+-----------+------+
7 rows in set (0.00 sec)
2.3.2 同學及 qq 號,按 qq 號排序顯示
# NULL 視為比任何值都小,升序出現在最上面
mysql> SELECT name, qq FROM students ORDER BY qq;
+-----------+-------+
| name | qq |
+-----------+-------+
| 唐大師 | NULL |
| 孫仲謀 | NULL |
| 曹阿瞞 | NULL |
| 孫悟空 | 11111 |
+-----------+-------+
4 rows in set (0.00 sec)# NULL 視為比任何值都小,降序出現在最下面
mysql> SELECT name, qq FROM students ORDER BY qq DESC;
+-----------+-------+
| name | qq |
+-----------+-------+
| 孫悟空 | 11111 |
| 唐大師 | NULL |
| 孫仲謀 | NULL |
| 曹阿瞞 | NULL |
+-----------+-------+
4 rows in set (0.00 sec)
2.3.3 查詢同學各門成績,依次按 數學降序,英語升序,語文升序的方式顯示
多字段排序,排序優先級隨書寫順序
# 優先數學降序,數學字段對應值相同時,英語升序...
mysql> 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 |
| 孫權 | 73 | 78 | 70 |
| 宋公明 | 65 | 30 | 75 |
+-----------+------+---------+---------+
7 rows in set (0.00 sec)
2.3.4 查詢同學及總分,由高到低
# order by 中可以使用表達式
mysql> SELECT name, chinese + english + math FROM exam_result-> ORDER BY chinese + english + math DESC;
+-----------+--------------------------+
| name | chinese + english + math |
+-----------+--------------------------+
| 豬悟能 | 276 |
| 孫悟空 | 242 |
| 曹孟德 | 233 |
| 唐三藏 | 221 |
| 孫權 | 221 |
| 劉玄德 | 185 |
| 宋公明 | 170 |
+-----------+--------------------------+
7 rows in set (0.00 sec)# ORDER BY 子句中可以使用列別名
mysql> SELECT name, chinese + english + math 總分 FROM exam_result ORDER BY 總分 DESC;
+-----------+--------+
| name | 總分 |
+-----------+--------+
| 豬悟能 | 276 |
| 孫悟空 | 242 |
| 曹孟德 | 233 |
| 唐三藏 | 221 |
| 孫權 | 221 |
| 劉玄德 | 185 |
| 宋公明 | 170 |
+-----------+--------+
7 rows in set (0.00 sec)
2.3.5 查詢姓孫的同學或者姓曹的同學數學成績,結果按數學成績由高到低顯示
# 結合 WHERE 子句和 ORDER BY 子句
mysql> SELECT name, math FROM exam_result-> WHERE name LIKE '孫%' OR name LIKE '曹%'-> ORDER BY math DESC;
+-----------+------+
| name | math |
+-----------+------+
| 曹孟德 | 84 |
| 孫悟空 | 78 |
| 孫權 | 73 |
+-----------+------+
3 rows in set (0.00 sec)
2.4 篩選分頁結果
語法:
-- 起始下標為 0
-- 從 s 開始,篩選 n 條結果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n
-- 從0 開始,篩選n 條結果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;
;
-- 從 s 開始,篩選 n 條結果,比第二種用法更明確,建議使用
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s;
建議:對未知表進行查詢時,最好加一條 LIMIT 1,避免因為表中數據過大,查詢全表數據導致數據庫卡死
案例:
按 id 進行分頁,每頁 3 條記錄,分別顯示 第 1、2、3 頁
# 第一頁
mysql> 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.01 sec)# 第二頁
mysql> 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 | 孫權 | 73 | 78 | 70 |
+----+-----------+------+---------+---------+
3 rows in set (0.00 sec)# 第三頁
mysql> 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)
3. Update
語法:
UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]
對查詢到的結果進行列值更新
案例:
3.1 單列變更
將孫悟空同學的數學成績變更為 80 分
# 查看原數據
mysql> SELECT name, math FROM exam_result WHERE name = '孫悟空';
+-----------+------+
| name | math |
+-----------+------+
| 孫悟空 | 78 |
+-----------+------+
1 row in set (0.01 sec)# 數據更新
mysql> UPDATE exam_result SET math = 80 WHERE name = '孫悟空';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0# 查看更新后數據
mysql> SELECT name, math FROM exam_result WHERE name = '孫悟空';
+-----------+------+
| name | math |
+-----------+------+
| 孫悟空 | 80 |
+-----------+------+
1 row in set (0.00 sec)
3.2 一次更新多個列
將曹孟德同學的數學成績變更為 60 分,語文成績變更為 70 分
# 查看原數據
mysql> SELECT name, math, chinese FROM exam_result WHERE name = '曹孟德';
+-----------+------+---------+
| name | math | chinese |
+-----------+------+---------+
| 曹孟德 | 84 | 82 |
+-----------+------+---------+
1 row in set (0.00 sec)# 數據更新
mysql> UPDATE exam_result SET math = 60, chinese = 70 WHERE name = '曹孟德';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0# 查看更新后數據
mysql> SELECT name, math, chinese FROM exam_result WHERE name = '曹孟德';
+-----------+------+---------+
| name | math | chinese |
+-----------+------+---------+
| 曹孟德 | 60 | 70 |
+-----------+------+---------+
1 row in set (0.00 sec)
3.3 更新值為原值基礎上進行變更
將總成績倒數前三的 3 位同學的數學成績加上 30 分
# 查看原數據,別名可以在 ORDER BY 中使用
mysql> 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)# 數據更新
mysql> UPDATE exam_result SET math = math + 30-> ORDER BY chinese + math + english LIMIT 3;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0# 查詢更新后的信息
mysql> 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)#
mysql> SELECT name, math, chinese + math + english 總分 FROM exam_result-> ORDER BY 總分 LIMIT 3;
+-----------+------+--------+
| name | math | 總分 |
+-----------+------+--------+
| 宋公明 | 95 | 200 |
| 劉玄德 | 115 | 215 |
| 唐三藏 | 98 | 221 |
+-----------+------+--------+
3 rows in set (0.00 sec)mysql> SELECT name, math, chinese + math + english 總分 FROM exam_result-> WHERE name IN ('宋公明', '劉玄德', '曹孟德') ORDER BY 總分 desc;
+-----------+------+--------+
| name | math | 總分 |
+-----------+------+--------+
| 曹孟德 | 90 | 227 |
| 劉玄德 | 115 | 215 |
| 宋公明 | 95 | 200 |
+-----------+------+--------+
3 rows in set (0.00 sec)
3.4 將所有同學的語文成績更新為原來的 2 倍
注意:更新全表語句慎用
- 沒有 WHERE 子句,更新全表
# 查看原數據
mysql> 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 | 孫權 | 70 | 73 | 78 |
| 7 | 宋公明 | 75 | 95 | 30 |
+----+-----------+---------+------+---------+
7 rows in set (0.01 sec)# 全表數據更新
mysql> UPDATE exam_result SET chinese = chinese * 2;
Query OK, 7 rows affected (0.06 sec)
Rows matched: 7 Changed: 7 Warnings: 0# 查看更新后數據
mysql> 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 | 孫權 | 140 | 73 | 78 |
| 7 | 宋公明 | 150 | 95 | 30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)
4. Delete
4.1 刪除數據
語法:
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]
案例:
4.1.1 刪除孫悟空同學的考試成績
# 查看原數據
mysql> SELECT * FROM exam_result WHERE name = '孫悟空';
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 2 | 孫悟空 | 174 | 80 | 77 |
+----+-----------+---------+------+---------+
1 row in set (0.00 sec)# 刪除數據
mysql> DELETE FROM exam_result WHERE name = '孫悟空';
Query OK, 1 row affected (0.00 sec)# 查看刪除結果
mysql> SELECT * FROM exam_result WHERE name = '孫悟空';
Empty set (0.00 sec)
4.1.2 刪除整張表數據
注意:刪除整表操作要慎用!
前置準備:
mysql> CREATE TABLE for_delete ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) );
Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0mysql> SELECT * FROM for_delete;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+
3 rows in set (0.00 sec)
刪除操作:
mysql> DELETE FROM for_delete;
Query OK, 3 rows affected (0.00 sec)mysql> SELECT * FROM for_delete;
Empty set (0.00 sec)
再插入一條數據,自增 id 在原值上增長
# 插入數據
mysql> INSERT INTO for_delete (name) VALUES ('D');
Query OK, 1 row affected (0.00 sec)mysql> SELECT * FROM for_delete;
+----+------+
| id | name |
+----+------+
| 4 | D |
+----+------+
1 row in set (0.00 sec)# 查看表結構,會有 AUTO_INCREMENT=n 項
mysql> SHOW CREATE TABLE for_delete\G;
*************************** 1. row ***************************Table: for_delete
Create Table: CREATE TABLE `for_delete` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)ERROR:
No query specified
4.2 截斷表
語法:
TRUNCATE [TABLE] table_name
注意:這個操作慎用
- 只能對整表操作,不能像 DELETE 一樣針對部分數據操作;
- 實際上 MySQL 不對數據操作,所以比 DELETE 更快,但是TRUNCATE在刪除數據的時候,并不經過真正的事務,所以無法回滾
- 會重置 AUTO_INCREMENT 項
前置準備:
mysql> CREATE TABLE for_truncate (-> id INT PRIMARY KEY AUTO_INCREMENT,-> name VARCHAR(20)-> );
Query OK, 0 rows affected (0.01 sec)mysql> INSERT INTO for_truncate (name) VALUES ('A'), ('B'), ('C');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0mysql> SELECT * FROM for_truncate;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+
3 rows in set (0.00 sec)
截斷操作:
mysql> TRUNCATE for_truncate;
Query OK, 0 rows affected (0.03 sec)mysql> SELECT * FROM for_truncate;
Empty set (0.00 sec)
再插入一條數據,自增 id 在重新增長:
# 插入數據
mysql> INSERT INTO for_truncate (name) VALUES ('D');
Query OK, 1 row affected (0.00 sec)mysql> SELECT * FROM for_truncate;
+----+------+
| id | name |
+----+------+
| 1 | D |
+----+------+
1 row in set (0.00 sec)# 查看表結構,會有 AUTO_INCREMENT=2 項
mysql> SHOW CREATE TABLE for_truncate\G;
*************************** 1. row ***************************Table: for_truncate
Create Table: CREATE TABLE `for_truncate` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)ERROR:
No query specified
5. 插入查詢結果(insert into… select…)
語法:
INSERT INTO table_name [(column [, column ...])] SELECT ...
案例:
刪除表中的的重復復記錄,重復的數據只能有一份
mysql> CREATE TABLE duplicate_table (id int, name varchar(20));
Query OK, 0 rows affected (0.01 sec)mysql> INSERT INTO duplicate_table VALUES-> (100, 'aaa'),-> (100, 'aaa'),-> (200, 'bbb'),-> (200, 'bbb'),-> (200, 'bbb'),-> (300, 'ccc');
Query OK, 6 rows affected (0.02 sec)
Records: 6 Duplicates: 0 Warnings: 0
思路:
# 創建一張空表 no_duplicate_table,結構和 duplicate_table 一樣
mysql> CREATE TABLE no_duplicate_table LIKE duplicate_table;
Query OK, 0 rows affected (0.00 sec)# 將 duplicate_table 的去重數據插入到 no_duplicate_table
mysql> INSERT INTO no_duplicate_table SELECT DISTINCT * FROM duplicate_table;
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0# 通過重命名表,實現原子的去重操作
mysql> RENAME TABLE duplicate_table TO old_duplicate_table,-> no_duplicate_table TO duplicate_table;
Query OK, 0 rows affected (0.04 sec)# 查看最終結果
mysql> SELECT * FROM duplicate_table;
+------+------+
| id | name |
+------+------+
| 100 | aaa |
| 200 | bbb |
| 300 | ccc |
+------+------+
3 rows in set (0.00 sec)
6. 聚合函數
案例:
6.1 統計班級共有多少同學
# 使用 * 做統計,不受 NULL 影響
mysql> SELECT COUNT(*) FROM students;
+----------+
| COUNT(*) |
+----------+
| 4 |
+----------+
1 row in set (0.01 sec)# 使用表達式做統計
mysql> SELECT COUNT(1) FROM students;
+----------+
| COUNT(1) |
+----------+
| 4 |
+----------+
1 row in set (0.00 sec)
6.2 統計班級收集的 qq 號有多少
# NULL 不會計入結果
mysql> SELECT COUNT(qq) FROM students;
+-----------+
| COUNT(qq) |
+-----------+
| 1 |
+-----------+
1 row in set (0.02 sec)
6.3 統計本次考試的數學成績分數個數
# 查看所有信息
mysql> SELECT * FROM exam_result;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 134 | 98 | 56 |
| 3 | 豬悟能 | 176 | 98 | 90 |
| 4 | 曹孟德 | 140 | 90 | 67 |
| 5 | 劉玄德 | 110 | 115 | 45 |
| 6 | 孫權 | 140 | 73 | 78 |
| 7 | 宋公明 | 150 | 95 | 30 |
+----+-----------+---------+------+---------+
6 rows in set (0.00 sec)# COUNT(math) 統計的是全部成績
mysql> SELECT COUNT(math) FROM exam_result;
+-------------+
| COUNT(math) |
+-------------+
| 6 |
+-------------+
1 row in set (0.00 sec)# COUNT(DISTINCT math) 統計的是去重成績數量
mysql> SELECT COUNT(DISTINCT math) FROM exam_result;
+----------------------+
| COUNT(DISTINCT math) |
+----------------------+
| 5 |
+----------------------+
1 row in set (0.00 sec)
6.4 統計數學成績總分
mysql> SELECT SUM(math) FROM exam_result;
+-----------+
| SUM(math) |
+-----------+
| 569 |
+-----------+
1 row in set (0.00 sec)# 不及格 < 60 的總分,沒有結果,返回 NULL
mysql> SELECT SUM(math) FROM exam_result WHERE math < 60;
+-----------+
| SUM(math) |
+-----------+
| NULL |
+-----------+
1 row in set (0.00 sec)
6.5 統計平均總分
mysql> SELECT AVG(chinese + math + english) 平均總分 FROM exam_result;
+--------------+
| 平均總分 |
+--------------+
| 297.5 |
+--------------+
1 row in set (0.00 sec)
6.6 返回英語最高分
mysql> SELECT MAX(english) FROM exam_result;
+--------------+
| MAX(english) |
+--------------+
| 90 |
+--------------+
1 row in set (0.00 sec)
6.7 返回 > 70 分以上的數學最低分
mysql> SELECT MIN(math) FROM exam_result WHERE math > 70;
+-----------+
| MIN(math) |
+-----------+
| 73 |
+-----------+
1 row in set (0.00 sec)
7. group by子句的使用
在 select 中使用 group by 子句可以對指定列進行分組查詢
select column1, column2, .. from table group by column;
案例:
-
準備工作,創建一個雇員信息表(來自oracle 9i的經典測試表)
-
emp 員工表
-
dept 部門表
-
salgrade 工資等級表
-
-
如何顯示每個部門的平均工資和最高工資
mysql> select deptno,avg(sal),max(sal) from emp group by deptno;
+--------+-------------+----------+
| deptno | avg(sal) | max(sal) |
+--------+-------------+----------+
| 20 | 2175.000000 | 3000.00 |
| 30 | 1566.666667 | 2850.00 |
| 10 | 2916.666667 | 5000.00 |
+--------+-------------+----------+
3 rows in set (0.00 sec)
- 顯示每個部門的每種崗位的平均工資和最低工資
mysql> select avg(sal),min(sal),job, deptno from emp group by deptno, job;
+-------------+----------+-----------+--------+
| avg(sal) | min(sal) | job | deptno |
+-------------+----------+-----------+--------+
| 950.000000 | 800.00 | CLERK | 20 |
| 1400.000000 | 1250.00 | SALESMAN | 30 |
| 2975.000000 | 2975.00 | MANAGER | 20 |
| 2850.000000 | 2850.00 | MANAGER | 30 |
| 2450.000000 | 2450.00 | MANAGER | 10 |
| 3000.000000 | 3000.00 | ANALYST | 20 |
| 5000.000000 | 5000.00 | PRESIDENT | 10 |
| 950.000000 | 950.00 | CLERK | 30 |
| 1300.000000 | 1300.00 | CLERK | 10 |
+-------------+----------+-----------+--------+
9 rows in set (0.00 sec)
- 顯示平均工資低于2000的部門和它的平均工資
mysql> select deptno, avg(sal) as 平均工資 from emp group by deptno having (平均工資<2000);
+--------+--------------+
| deptno | 平均工資 |
+--------+--------------+
| 30 | 1566.666667 |
+--------+--------------+
1 row in set (0.00 sec)