赞
踩
目录
1.9 MySQL 8.0 新特性 1 - GROUP BY 不再隐式排序
1.10 MySQL 8.0 新特性 2 - 通用表达式 CET
MySQL 从数据库表中查询数据的基本语句为 SELECT 语句。基本格式为:
- SELECT
- {* | <字段列表>}
- [
- FROM [<视图1>, <视图2>... | <表1>,<表2>...]
- [WHERE <表达式>]
- [GROUP BY <字段名>]
- [HAVING <表达式>]
- [ORDER BY <字段名>]
- [LIMIT [<起始位置>,] <总数>]
- ]
- mysql> CREATE TABLE day_expenditure
- -> (
- -> id INT AUTO_INCREMENT PRIMARY KEY,
- -> item VARCHAR(10) NOT NULL,
- -> place VARCHAR(20),
- -> expend FLOAT,
- -> time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
- -> );
- Query OK, 0 rows affected (0.03 sec)
需要注意,TIMESTAMP 默认值有几种模式:
- mysql> SHOW VARIABLES LIKE 'explicit_defaults_for_timestamp';
- +---------------------------------+-------+
- | Variable_name | Value |
- +---------------------------------+-------+
- | explicit_defaults_for_timestamp | ON |
- +---------------------------------+-------+
- 1 row in set, 1 warning (0.00 sec)
-
- // 若以上值为 OFF,需要手动将其设置为 ON
- mysql> SET @@global.explicit_defaults_for_timestamp=ON;
- Query OK, 0 rows affected (0.00 sec)
创建存储过程方便批量插入数据:
- mysql> DELIMITER $;
- mysql> CREATE PROCEDURE batchInsertExpends(in args INT)
- -> BEGIN
- -> DECLARE i INT DEFAULT 1;
- -> START TRANSACTION;
- -> WHILE i <= args DO
- -> INSERT INTO day_expenditure(`item`, `place`, `expend`) VALUES('吃饭', '广发银行千灯湖食堂', 20);
- -> SET i = i + 1;
- -> END WHILE;
- -> COMMIT;
- -> END
- -> $;
- Query OK, 0 rows affected (0.02 sec)
mysql> CALL batchInsertExpends(1000);
1. 使用 * 通配符查询所有字段。
- mysql> SELECT * FROM day_expenditure;
- +------+--------+-----------------------------+--------+---------------------+
- | id | item | place | expend | time |
- +------+--------+-----------------------------+--------+---------------------+
- | 1 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 2 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 3 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 4 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 5 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 6 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 7 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 8 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 9 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 10 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 11 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 12 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 13 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 14 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 15 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 16 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 17 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 18 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 19 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 20 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 21 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- ......
2. 查询指定字段
- mysql> SELECT item, expend FROM day_expenditure;
- +--------+--------+
- | item | expend |
- +--------+--------+
- | 吃饭 | 20 |
- | 吃饭 | 20 |
- | 吃饭 | 20 |
- | 吃饭 | 20 |
- | 吃饭 | 20 |
- | 吃饭 | 20 |
- ......
- | 吃饭 | 20 |
- | 吃饭 | 20 |
- | 吃饭 | 20 |
- | 吃饭 | 20 |
- | 吃饭 | 20 |
- | 吃饭 | 20 |
- +--------+--------+
- 1000 rows in set (0.00 sec)
MySQL 中的 SQL 语句是不区分大小写的,但是读者应该养成一个良好的习惯,关键字大写,表名和列名小写,这样写出来的 SQL 会更容易维护一些。
3. 查询指定记录
数据库表中的数据是相当多的,一般情况下,我们都不会查出全部数据,而是需要部分满足我们条件的数据,这时就可以使用 WHERE 子句加上一些条件判断表达式对我们的数据进行过滤。
- mysql> SELECT item, place FROM day_expenditure WHERE id=45;
- +--------+-----------------------------+
- | item | place |
- +--------+-----------------------------+
- | 吃饭 | 广发银行千灯湖食堂 |
- +--------+-----------------------------+
- 1 row in set (0.00 sec)
4. 关键字 IN 和 NOT IN 查询
- mysql> SELECT * FROM day_expenditure WHERE id IN (101, 954);
- +-----+--------+-----------------------------+--------+---------------------+
- | id | item | place | expend | time |
- +-----+--------+-----------------------------+--------+---------------------+
- | 101 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 954 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- +-----+--------+-----------------------------+--------+---------------------+
- 2 rows in set (0.00 sec)
- mysql> SELECT * FROM day_expenditure WHERE id NOT IN (SELECT id FROM day_expenditure WHERE id >1);
- +----+--------+-----------------------------+--------+---------------------+
- | id | item | place | expend | time |
- +----+--------+-----------------------------+--------+---------------------+
- | 1 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- +----+--------+-----------------------------+--------+---------------------+
- 1 row in set (0.01 sec)
5. 范围查询
- mysql> SELECT id, item, place FROM day_expenditure WHERE id BETWEEN 996 AND 998;
- +-----+--------+-----------------------------+
- | id | item | place |
- +-----+--------+-----------------------------+
- | 996 | 吃饭 | 广发银行千灯湖食堂 |
- | 997 | 吃饭 | 广发银行千灯湖食堂 |
- | 998 | 吃饭 | 广发银行千灯湖食堂 |
- +-----+--------+-----------------------------+
- 3 rows in set (0.01 sec)
- mysql> SELECT * FROM day_expenditure WHERE id >= 45 AND id <= 54;
- +----+--------+-----------------------------+--------+---------------------+
- | id | item | place | expend | time |
- +----+--------+-----------------------------+--------+---------------------+
- | 45 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 46 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 47 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 48 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 49 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 50 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 51 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 52 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 53 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 54 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- +----+--------+-----------------------------+--------+---------------------+
- 10 rows in set (0.00 sec)
6. 字符匹配查询
可以使用 LIKE 关键字,也可以使用 REGEXP 关键字进行字符串匹配。
- mysql> INSERT INTO day_expenditure(item, place, expend, time) VALUES('烧烤', '青岛精酿', 121, NULL);
- Query OK, 1 row affected (0.01 sec)
LIKE:
- // 匹配以岛开头的字符串
- mysql> SELECT * FROM day_expenditure WHERE place LIKE '岛%';
- Empty set (0.00 sec)
-
- // 匹配以青开头的字符串
- mysql> SELECT * FROM day_expenditure WHERE place LIKE '青%';
- +------+--------+--------------+--------+------+
- | id | item | place | expend | time |
- +------+--------+--------------+--------+------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+--------------+--------+------+
- 1 row in set (0.00 sec)
-
- // 匹配包含岛的字符串
- mysql> SELECT * FROM day_expenditure WHERE place LIKE '%岛%';
- +------+--------+--------------+--------+------+
- | id | item | place | expend | time |
- +------+--------+--------------+--------+------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+--------------+--------+------+
- 1 row in set (0.00 sec)
-
- // 匹配以酒结尾的字符串
- mysql> SELECT * FROM day_expenditure WHERE place LIKE '%酒';
- Empty set (0.00 sec)
-
- // 匹配以酿结尾的字符串
- mysql> SELECT * FROM day_expenditure WHERE place LIKE '%酿';
- +------+--------+--------------+--------+------+
- | id | item | place | expend | time |
- +------+--------+--------------+--------+------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+--------------+--------+------+
- 1 row in set (0.00 sec)
-
- // 匹配两个字符长的第二个字符是岛的字符串
- mysql> SELECT * FROM day_expenditure WHERE place LIKE '_岛';
- Empty set (0.00 sec)
-
- // 匹配四个字符长的第二个字符是岛的字符串
- mysql> SELECT * FROM day_expenditure WHERE place LIKE '_岛__';
- +------+--------+--------------+--------+------+
- | id | item | place | expend | time |
- +------+--------+--------------+--------+------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+--------------+--------+------+
- 1 row in set (0.00 sec)
-
- // 匹配四个字符长的字符串
- mysql> SELECT * FROM day_expenditure WHERE place LIKE '____';
- +------+--------+--------------+--------+------+
- | id | item | place | expend | time |
- +------+--------+--------------+--------+------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+--------------+--------+------+
- 1 row in set (0.00 sec)
REGEXP:
- // 匹配以青开头的字符串
- mysql> SELECT * FROM day_expenditure WHERE place REGEXP '^青';
- +------+--------+--------------+--------+------+
- | id | item | place | expend | time |
- +------+--------+--------------+--------+------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+--------------+--------+------+
- 1 row in set (0.02 sec)
-
- // 匹配以岛开头的字符串
- mysql> SELECT * FROM day_expenditure WHERE place REGEXP '^岛';
- Empty set (0.00 sec)
-
- // 匹配以精结尾的字符串
- mysql> SELECT * FROM day_expenditure WHERE place REGEXP '精$';
- Empty set (0.00 sec)
-
- // 匹配以酿尾的字符串
- mysql> SELECT * FROM day_expenditure WHERE place REGEXP '酿$';
- +------+--------+--------------+--------+------+
- | id | item | place | expend | time |
- +------+--------+--------------+--------+------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+--------------+--------+------+
- 1 row in set (0.00 sec)
-
- // 匹配包含精的字符串
- mysql> SELECT * FROM day_expenditure WHERE place REGEXP '.精';
- +------+--------+--------------+--------+------+
- | id | item | place | expend | time |
- +------+--------+--------------+--------+------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+--------------+--------+------+
- 1 row in set (0.00 sec)
-
- // 匹配包含酒的字符串
- mysql> SELECT * FROM day_expenditure WHERE place REGEXP '.酒';
- Empty set (0.00 sec)
-
- // 匹配包含烤肉的任意一个字符的字符串
- mysql> SELECT * FROM day_expenditure WHERE item REGEXP '[烤肉]';
- +------+--------+--------------+--------+------+
- | id | item | place | expend | time |
- +------+--------+--------------+--------+------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+--------------+--------+------+
- 1 row in set (0.00 sec)
7. 空值查询 IS NULL 与 非空值查询 IS NOT NULL
- mysql> SELECT * FROM day_expenditure WHERE time IS NULL;
- +------+--------+--------------+--------+------+
- | id | item | place | expend | time |
- +------+--------+--------------+--------+------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+--------------+--------+------+
- 1 row in set (0.00 sec)
-
-
- mysql> SELECT * FROM day_expenditure WHERE time IS NOT NULL;
- +------+--------+-----------------------------+--------+---------------------+
- | id | item | place | expend | time |
- +------+--------+-----------------------------+--------+---------------------+
- | 1 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 2 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- ......
- | 998 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 999 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 1000 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- +------+--------+-----------------------------+--------+---------------------+
- 1000 rows in set (0.00 sec)
8. 多条件查询 AND、OR
- mysql> SELECT * FROM day_expenditure WHERE time IS NULL OR id=1;
- +------+--------+-----------------------------+--------+---------------------+
- | id | item | place | expend | time |
- +------+--------+-----------------------------+--------+---------------------+
- | 1 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+-----------------------------+--------+---------------------+
- 2 rows in set (0.00 sec)
-
- mysql> SELECT * FROM day_expenditure WHERE time IS NULL AND id=1;
- Empty set (0.01 sec)
9. 查询不重复的结果
- mysql> SELECT DISTINCT item, place, expend, time FROM day_expenditure;
- +--------+-----------------------------+--------+---------------------+
- | item | place | expend | time |
- +--------+-----------------------------+--------+---------------------+
- | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 烧烤 | 青岛精酿 | 121 | NULL |
- +--------+-----------------------------+--------+---------------------+
- 2 rows in set (0.00 sec)
10. 排序查询结果
- mysql> SELECT * FROM day_expenditure WHERE id > 999 ORDER BY place DESC;
- +------+--------+-----------------------------+--------+---------------------+
- | id | item | place | expend | time |
- +------+--------+-----------------------------+--------+---------------------+
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- | 1000 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- +------+--------+-----------------------------+--------+---------------------+
- 2 rows in set (0.00 sec)
- mysql> SELECT * FROM day_expenditure WHERE id >= 999 ORDER BY expend, item ASC;
- +------+--------+-----------------------------+--------+---------------------+
- | id | item | place | expend | time |
- +------+--------+-----------------------------+--------+---------------------+
- | 999 | 吃面 | 广发银行千灯湖食堂 | 20 | 2022-05-25 17:11:29 |
- | 1000 | 吃饭 | 广发银行千灯湖食堂 | 20 | 2022-05-25 15:38:04 |
- | 1001 | 烧烤 | 青岛精酿 | 121 | NULL |
- +------+--------+-----------------------------+--------+---------------------+
- 3 rows in set (0.00 sec)
11. 分组查询
- mysql> SELECT item, place, SUM(expend) FROM day_expenditure GROUP BY item, place;
- +--------------+-----------------------------+-------------+
- | item | place | SUM(expend) |
- +--------------+-----------------------------+-------------+
- | 吃饭 | 广发银行千灯湖食堂 | 220 |
- | 烧烤 | 青岛精酿 | 121 |
- | 打车 | 上下班 | 66 |
- | 吃饭 | 万科金色领域 | 290 |
- | 买波罗蜜 | 广发东门 | 25 |
- +--------------+-----------------------------+-------------+
- 5 rows in set (0.00 sec)
注意:GROUP BY 关键字通常和分组函数 MAX()、MIN()、COUNT()、SUM()、AVG() 联合使用,并且,SELECT 关键字后面跟的字段要么是分组的字段,要么就是使用了分组函数,否则,以该字段查询出来的列数据也只是取了第一行数据的值显示,毫无意义,甚至造成歧义或问题。
- mysql> SELECT item, place, SUM(expend) FROM day_expenditure GROUP BY item;
- +--------------+-----------------------------+-------------+
- | item | place | SUM(expend) |
- +--------------+-----------------------------+-------------+
- | 吃饭 | 广发银行千灯湖食堂 | 510 |
- | 烧烤 | 青岛精酿 | 121 |
- | 打车 | 上下班 | 66 |
- | 买波罗蜜 | 广发东门 | 25 |
- +--------------+-----------------------------+-------------+
- 4 rows in set (0.00 sec)
使用 HAVING 过滤分组:
- mysql> SELECT item, place, SUM(expend) FROM day_expenditure GROUP BY item, place HAVING SUM(expend) > 100;
- +--------+-----------------------------+-------------+
- | item | place | SUM(expend) |
- +--------+-----------------------------+-------------+
- | 吃饭 | 广发银行千灯湖食堂 | 220 |
- | 烧烤 | 青岛精酿 | 121 |
- | 吃饭 | 万科金色领域 | 290 |
- +--------+-----------------------------+-------------+
- 3 rows in set (0.00 sec)
- mysql> SELECT item, place, SUM(expend) FROM day_expenditure GROUP BY item, place HAVING item REGEXP '.饭';
- +--------+-----------------------------+-------------+
- | item | place | SUM(expend) |
- +--------+-----------------------------+-------------+
- | 吃饭 | 广发银行千灯湖食堂 | 220 |
- | 吃饭 | 万科金色领域 | 290 |
- +--------+-----------------------------+-------------+
- 2 rows in set (0.00 sec)
HAVING 与 WHERE 的区别:
HAVING 在分组之后过滤数据,WHERE 在分组之前过滤数据,被 WHERE 过滤掉的数据不包含在分组之中。
- mysql> SELECT item, place, SUM(expend) FROM day_expenditure WHERE item REGEXP '.饭' GROUP BY item, place HAVING SUM(expend) > 100;
- +--------+-----------------------------+-------------+
- | item | place | SUM(expend) |
- +--------+-----------------------------+-------------+
- | 吃饭 | 广发银行千灯湖食堂 | 220 |
- | 吃饭 | 万科金色领域 | 290 |
- +--------+-----------------------------+-------------+
- 2 rows in set (0.00 sec)
使用 ORDER BY 排序分组:
- mysql> SELECT item, place, SUM(expend) AS sumexpend FROM day_expenditure WHERE item REGEXP '.饭' GROUP BY item, place HAVING SUM(expend) > 100 ORDER BY sumexpend DESC;
- +--------+-----------------------------+-----------+
- | item | place | sumexpend |
- +--------+-----------------------------+-----------+
- | 吃饭 | 万科金色领域 | 290 |
- | 吃饭 | 广发银行千灯湖食堂 | 220 |
- +--------+-----------------------------+-----------+
- 2 rows in set (0.00 sec)
使用 WITH ROLLUP 统计分组函数总量:
- mysql> SELECT item, place, SUM(expend) AS sumexpend FROM day_expenditure GROUP BY item, place WITH ROLLUP;
- +--------------+-----------------------------+-----------+
- | item | place | sumexpend |
- +--------------+-----------------------------+-----------+
- | 买波罗蜜 | 广发东门 | 25 |
- | 买波罗蜜 | NULL | 25 |
- | 吃饭 | 万科金色领域 | 290 |
- | 吃饭 | 广发银行千灯湖食堂 | 220 |
- | 吃饭 | NULL | 510 |
- | 打车 | 上下班 | 66 |
- | 打车 | NULL | 66 |
- | 烧烤 | 青岛精酿 | 121 |
- | 烧烤 | NULL | 121 |
- | NULL | NULL | 722 |
- +--------------+-----------------------------+-----------+
- 10 rows in set (0.00 sec)
WITH ROLLUP 会对每一列分组字段进行一次分组函数列的总量求和,然后对所有列分组字段进行一次分组函数的总量求和。
函数 | 作用 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值的和 |
1. COUNT() 函数
统计数据表中包含的记录行的总数,有两种用法:
- mysql> SELECT item, place, COUNT(*) FROM day_expenditure GROUP BY item, place HAVING SUM(expend) > 100;
- +--------+-----------------------------+----------+
- | item | place | COUNT(*) |
- +--------+-----------------------------+----------+
- | 吃饭 | 广发银行千灯湖食堂 | 11 |
- | 烧烤 | 青岛精酿 | 1 |
- | 吃饭 | 万科金色领域 | 5 |
- +--------+-----------------------------+----------+
- 3 rows in set (0.00 sec)
- mysql> SELECT item, place, COUNT(time) AS count FROM day_expenditure GROUP BY item, place HAVING SUM(expend) > 100;
- +--------+-----------------------------+-------+
- | item | place | count |
- +--------+-----------------------------+-------+
- | 吃饭 | 广发银行千灯湖食堂 | 11 |
- | 烧烤 | 青岛精酿 | 0 |
- | 吃饭 | 万科金色领域 | 5 |
- +--------+-----------------------------+-------+
- 3 rows in set (0.00 sec)
2. SUM() 函数是一个求总和的函数,可以与 GROUP BY 组合使用计算每个分组的某几列值总和。
- mysql> SELECT item, place, SUM(expend) AS sum FROM day_expenditure GROUP BY item, place HAVING SUM(expend) > 100;
- +--------+-----------------------------+------+
- | item | place | sum |
- +--------+-----------------------------+------+
- | 吃饭 | 广发银行千灯湖食堂 | 220 |
- | 烧烤 | 青岛精酿 | 121 |
- | 吃饭 | 万科金色领域 | 290 |
- +--------+-----------------------------+------+
- 3 rows in set (0.00 sec)
-
- mysql> SELECT SUM(expend) AS sum FROM day_expenditure;
- +------+
- | sum |
- +------+
- | 722 |
- +------+
- 1 row in set (0.01 sec)
3. AVG() 计算平均值的函数,可以与 GROUP BY 组合使用计算每个分组的某几列的平均值。
- mysql> SELECT item, place, AVG(expend) AS avg FROM day_expenditure GROUP BY item, place;
- +--------------+-----------------------------+------+
- | item | place | avg |
- +--------------+-----------------------------+------+
- | 吃饭 | 广发银行千灯湖食堂 | 20 |
- | 烧烤 | 青岛精酿 | 121 |
- | 打车 | 上下班 | 11 |
- | 吃饭 | 万科金色领域 | 58 |
- | 买波罗蜜 | 广发东门 | 12.5 |
- +--------------+-----------------------------+------+
- 5 rows in set (0.00 sec)
4. MAX() 求某列或分别某几列的最大值,可以与 GROUP BY 组合使用。
- mysql> SELECT item, MAX(expend) AS max FROM day_expenditure GROUP BY item;
- +--------------+------+
- | item | max |
- +--------------+------+
- | 吃饭 | 58 |
- | 烧烤 | 121 |
- | 打车 | 11 |
- | 买波罗蜜 | 15 |
- +--------------+------+
- 4 rows in set (0.00 sec)
-
- mysql> SELECT MAX(expend) AS max FROM day_expenditure;
- +------+
- | max |
- +------+
- | 121 |
- +------+
- 1 row in set (0.00 sec)
5. MIN() 求某几列的最小值,可以与 GROUP BY 组合使用。
- mysql> SELECT item, MIN(expend) AS max FROM day_expenditure GROUP BY item;
- +--------------+------+
- | item | max |
- +--------------+------+
- | 吃饭 | 20 |
- | 烧烤 | 121 |
- | 打车 | 11 |
- | 买波罗蜜 | 10 |
- +--------------+------+
- 4 rows in set (0.01 sec)
单独使用聚合函数的时候,SELECT 后面跟的字段也必须是分组函数的参数或是被分组的列,否则就会出现像下面这样的混乱。
- mysql> SELECT item, MIN(expend) AS max FROM day_expenditure;
- +--------+------+
- | item | max |
- +--------+------+
- | 吃饭 | 10 |
- +--------+------+
- 1 row in set (0.00 sec)
客官可以采用另外的方式达到你的目的,如:
- mysql> SELECT item, MIN(expend) AS max FROM day_expenditure GROUP BY item HAVING max <= 10;
- +--------------+------+
- | item | max |
- +--------------+------+
- | 买波罗蜜 | 10 |
- +--------------+------+
连接是关系型数据库的主要特点。连接查询是关系型数据库中最主要的查询,主要包括内连接、外连接等。通常连接运算符可以实现多个表查询。
1. 内连接查询
内连接(INNER JOIN) 使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行,组成新的记录,也就是说,在内连接查询中,只有满足条件的记录才能出现在查询结果之中。
- mysql> CREATE TABLE place_star
- -> (
- -> id INT AUTO_INCREMENT PRIMARY KEY,
- -> place VARCHAR(24) NOT NULL,
- -> star VARCHAR(6)
- -> );
- Query OK, 0 rows affected (0.03 sec)
-
- mysql> INSERT INTO place_star(place, star) VALUES('广发银行千灯湖食堂', '※※※'), ('青岛精酿', '※※'), ('万科金色领域, '※'), ('蒲二炭烤肉', '※※※※※'), ('胡老大', '※※※※');
- Query OK, 5 rows affected (0.01 sec)
- Records: 5 Duplicates: 0 Warnings: 0
- mysql> SELECT * FROM place_star;
- +----+-----------------------------+-----------------+
- | id | place | star |
- +----+-----------------------------+-----------------+
- | 1 | 广发银行千灯湖食堂 | ※※※ |
- | 2 | 青岛精酿 | ※※ |
- | 3 | 万科金色领域 | ※ |
- | 4 | 蒲二炭烤肉 | ※※※※※ |
- | 5 | 胡老大 | ※※※※ |
- +----+-----------------------------+-----------------+
- 5 rows in set (0.00 sec)
- mysql> SELECT item, a.place AS place, star, expend FROM day_expenditure AS a, place_star AS b WHERE a.place = b.place;
- +--------+-----------------------------+-----------+--------+
- | item | place | star | expend |
- +--------+-----------------------------+-----------+--------+
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 烧烤 | 青岛精酿 | ※※ | 121 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- +--------+-----------------------------+-----------+--------+
- 17 rows in set (0.00 sec)
两个表中如果存在相同的字段名,需要指明格式为表名.字段名,否则,MySQL 不知道指的是哪个表中的该字段,将会报错。
使用 INNER JOIN 语法时,要用 ON 关键字指定连接条件。
- mysql> SELECT item, a.place AS place, star, expend FROM day_expenditure AS a INNER JOIN place_star AS b ON a.place = b.place;
- +--------+-----------------------------+-----------+--------+
- | item | place | star | expend |
- +--------+-----------------------------+-----------+--------+
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 烧烤 | 青岛精酿 | ※※ | 121 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- +--------+-----------------------------+-----------+--------+
- 17 rows in set (0.00 sec)
如果进行内连接的两张表物理上是同一张表,则称为自连接。
这个暂时先不举例了,之后有空再补充吧。
2. 外连接查询
连接查询时有时候需要包含没有满足关联条件的行,这时就要用外连接,分为如下几种:
LEFT [OUTER] JOIN,未满足匹配条件的右表数据将置为 NULL。
- mysql> SELECT item, a.place AS place, star, expend FROM day_expenditure AS a LEFT JOIN place_star AS b ON a.place = b.place;
- +--------------+-----------------------------+-----------+--------+
- | item | place | star | expend |
- +--------------+-----------------------------+-----------+--------+
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 烧烤 | 青岛精酿 | ※※ | 121 |
- | 打车 | 上下班 | NULL | 11 |
- | 打车 | 上下班 | NULL | 11 |
- | 打车 | 上下班 | NULL | 11 |
- | 打车 | 上下班 | NULL | 11 |
- | 打车 | 上下班 | NULL | 11 |
- | 打车 | 上下班 | NULL | 11 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 买波罗蜜 | 广发东门 | NULL | 10 |
- | 买波罗蜜 | 广发东门 | NULL | 15 |
- +--------------+-----------------------------+-----------+--------+
- 25 rows in set (0.00 sec)
-
- mysql> SELECT item, a.place AS place, star, expend FROM day_expenditure AS a LEFT OUTER JOIN place_star AS b ON a.place = b.place;
- +--------------+-----------------------------+-----------+--------+
- | item | place | star | expend |
- +--------------+-----------------------------+-----------+--------+
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 烧烤 | 青岛精酿 | ※※ | 121 |
- | 打车 | 上下班 | NULL | 11 |
- | 打车 | 上下班 | NULL | 11 |
- | 打车 | 上下班 | NULL | 11 |
- | 打车 | 上下班 | NULL | 11 |
- | 打车 | 上下班 | NULL | 11 |
- | 打车 | 上下班 | NULL | 11 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 买波罗蜜 | 广发东门 | NULL | 10 |
- | 买波罗蜜 | 广发东门 | NULL | 15 |
- +--------------+-----------------------------+-----------+--------+
- 25 rows in set (0.00 sec)
RIGHT [OUTER] JOIN,未满足匹配条件的左表数据将置为 NULL。
- mysql> SELECT item, b.place AS place, star, expend FROM day_expenditure AS a RIGHT JOIN place_star AS b ON a.place = b.place;
- +--------+-----------------------------+-----------------+--------+
- | item | place | star | expend |
- +--------+-----------------------------+-----------------+--------+
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 烧烤 | 青岛精酿 | ※※ | 121 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | NULL | 蒲二炭烤肉 | ※※※※※ | NULL |
- | NULL | 胡老大 | ※※※※ | NULL |
- +--------+-----------------------------+-----------------+--------+
- 19 rows in set (0.00 sec)
-
- mysql> SELECT item, b.place AS place, star, expend FROM day_expenditure AS a RIGHT OUTER JOIN place_star AS b ON a.place = b.place;
- +--------+-----------------------------+-----------------+--------+
- | item | place | star | expend |
- +--------+-----------------------------+-----------------+--------+
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 吃饭 | 广发银行千灯湖食堂 | ※※※ | 20 |
- | 烧烤 | 青岛精酿 | ※※ | 121 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | 吃饭 | 万科金色领域 | ※ | 58 |
- | NULL | 蒲二炭烤肉 | ※※※※※ | NULL |
- | NULL | 胡老大 | ※※※※ | NULL |
- +--------+-----------------------------+-----------------+--------+
- 19 rows in set (0.00 sec)
子查询指一个查询语句嵌套在另一个查询语句内部的查询。在 SELECT 子句中先计算子查询,子查询的结果作为外层另一个查询的过滤条件,查询可以基于一个表或多个表。子查询中常用的操作符有 ANY(SOME)、ALL、IN、EXISTS。子查询可以添加岛 SELECT、UPDATE、DELETE 语句中,而且可以进行多层嵌套。子查询中也可以使用比较运算符,如 ”<“, ">", "<=", ">=", "!=" 等。
1. 带 ANY、SOME 关键字的子查询
ANY、SOME 关键字表示只要满足任意一个就返回 TRUE。
- mysql> CREATE TABLE tb1 (nums1 INT NOT NULL);
- Query OK, 0 rows affected (0.03 sec)
-
- mysql> CREATE TABLE tb2 (nums2 INT NOT NULL);
- Query OK, 0 rows affected (0.03 sec)
-
- mysql> INSERT INTO tb1 VALUES(1), (5), (13), (27);
- Query OK, 4 rows affected (0.01 sec)
- Records: 4 Duplicates: 0 Warnings: 0
-
- mysql> INSERT INTO tb2 VALUES(6), (14), (11), (10);
- Query OK, 4 rows affected (0.01 sec)
- Records: 4 Duplicates: 0 Warnings: 0
-
- mysql> SELECT nums1 FROM tb1;
- +-------+
- | nums1 |
- +-------+
- | 1 |
- | 5 |
- | 13 |
- | 27 |
- +-------+
- 4 rows in set (0.00 sec)
-
- mysql> SELECT nums2 FROM tb2;
- +-------+
- | nums2 |
- +-------+
- | 6 |
- | 14 |
- | 11 |
- | 10 |
- +-------+
- 4 rows in set (0.00 sec)
- mysql> SELECT nums1 FROM tb1 WHERE nums1 > ANY (SELECT nums2 FROM tb2);
- +-------+
- | nums1 |
- +-------+
- | 13 |
- | 27 |
- +-------+
- 2 rows in set (0.00 sec)
-
- mysql> SELECT nums1 FROM tb1 WHERE nums1 > SOME (SELECT nums2 FROM tb2);
- +-------+
- | nums1 |
- +-------+
- | 13 |
- | 27 |
- +-------+
- 2 rows in set (0.00 sec)
2. 带 ALL 关键字的子查询
ALL 关键字表示外层需要满足内层结果集中的所有结果才能通过过滤。
- mysql> SELECT nums1 FROM tb1 WHERE nums1 > ALL (SELECT nums2 FROM tb2);
- +-------+
- | nums1 |
- +-------+
- | 27 |
- +-------+
- 1 row in set (0.00 sec)
3. 带 EXISTS、NOT EXISTS 关键字的子查询
EXISTS 关键字后面的参数可以是任意一个子查询,子查询的结果集值本身没有太大意义,系统对子查询进行运算以判断它是否返回行,如果至少返回一行,则 EXISTS 返回 TRUE ,此时外层查询才进行查询;若子查询没有返回任何行,那么 EXISTS 结果为 FALSE ,此时外层不进行查询。
- mysql> SELECT nums1 FROM tb1 WHERE EXISTS (SELECT nums2 FROM tb2 WHERE nums2 > 10);
- +-------+
- | nums1 |
- +-------+
- | 1 |
- | 5 |
- | 13 |
- | 27 |
- +-------+
- 4 rows in set (0.00 sec)
-
- mysql> SELECT nums1 FROM tb1 WHERE EXISTS (SELECT nums2 FROM tb2 WHERE nums2 > 14);
- Empty set (0.00 sec)
NOT EXISTS 关键字与 EXISTS 正好相反,若子查询没有返回则外层进行查询,否则哪怕返回一行外层查询也会进行。
- mysql> SELECT nums1 FROM tb1 WHERE NOT EXISTS (SELECT nums2 FROM tb2 WHERE nums2 > 14);
- +-------+
- | nums1 |
- +-------+
- | 1 |
- | 5 |
- | 13 |
- | 27 |
- +-------+
- 4 rows in set (0.00 sec)
-
- mysql> SELECT nums1 FROM tb1 WHERE NOT EXISTS (SELECT nums2 FROM tb2 WHERE nums2 > 11);
- Empty set (0.00 sec)
4. 使用带 IN 的关键子查询
IN 关键字在子查询查出的数据列表中进行过滤,看外层查询的值是否在子查询的结果集中, NOT IN 与此相反。
- mysql> SELECT nums1 FROM tb1 WHERE nums1 IN (SELECT nums2 FROM tb2);
- Empty set (0.00 sec)
-
- mysql> SELECT nums1 FROM tb1 WHERE nums1 NOT IN (SELECT nums2 FROM tb2);
- +-------+
- | nums1 |
- +-------+
- | 1 |
- | 5 |
- | 13 |
- | 27 |
- +-------+
- 4 rows in set (0.00 sec)
5. 带比较运算符的子查询
- mysql> SELECT nums1 FROM tb1 WHERE nums1 <> (SELECT nums2 FROM tb2 WHERE nums2=11);
- +-------+
- | nums1 |
- +-------+
- | 1 |
- | 5 |
- | 13 |
- | 27 |
- +-------+
- 4 rows in set (0.00 sec)
利用 UNION 关键字合并多条 SELECT 语句的查询结果,合并的前提是查询出的结果集的列数和数据类型必须相同。各个 SELECT 语句使用 UNION 或 UNION ALL 连接,两者的区别是 UNION 会去重,而 UNION ALL 不会。
- mysql> INSERT INTO tb1 VALUES(66);
- Query OK, 1 row affected (0.01 sec)
-
- mysql> INSERT INTO tb2 VALUES(66);
- Query OK, 1 row affected (0.00 sec)
-
- mysql> SELECT * FROM tb1;
- +-------+
- | nums1 |
- +-------+
- | 1 |
- | 5 |
- | 13 |
- | 27 |
- | 66 |
- +-------+
- 5 rows in set (0.00 sec)
-
- mysql> SELECT * FROM tb2;
- +-------+
- | nums2 |
- +-------+
- | 6 |
- | 14 |
- | 11 |
- | 10 |
- | 66 |
- +-------+
- 5 rows in set (0.00 sec)
- mysql> SELECT nums1 FROM tb1 UNION SELECT nums2 FROM tb2;
- +-------+
- | nums1 |
- +-------+
- | 1 |
- | 5 |
- | 13 |
- | 27 |
- | 66 |
- | 6 |
- | 14 |
- | 11 |
- | 10 |
- +-------+
- 9 rows in set (0.00 sec)
-
- mysql> SELECT nums1 FROM tb1 UNION ALL SELECT nums2 FROM tb2;
- +-------+
- | nums1 |
- +-------+
- | 1 |
- | 5 |
- | 13 |
- | 27 |
- | 66 |
- | 6 |
- | 14 |
- | 11 |
- | 10 |
- | 66 |
- +-------+
- 10 rows in set (0.00 sec)
当表名过长或字段过长时,可以取别名,注意不能与其它表名或字段名冲突。
表名 [AS] 表别名
字段 [AS] 字段别名
MySQL 中使用 REGEXP 关键字指定正则表达式的字符匹配模式。
选项 | 说明 | 例子 | 匹配值实例 |
---|---|---|---|
^ | 匹配文本的开始字符 | '^b' 匹配以 b 开头的字符串 | book、backup |
$ | 匹配文本的结束字符 | 'a$' 匹配以 b 结束的字符串 | NBA、cba |
. | 匹配任何单个字符 | 'b.t' 匹配任何 b 和 t 之间有一个字符的字符串 | bit、but |
* | 匹配零个或多个在它前面的字符 | 't*x' 匹配字符 x 前面有任意个字符 t 的字符串 | x、tx、ttx |
+ | 匹配一个或多个在它前面的字符 | 'tx+'匹配以 t 开头后面至少跟一个字符 x 的字符串 | txt、txx |
str | 匹配包含str字符串的文本 | 'tx' 匹配任何包含 tx 的字符串 | ltx、ltx666 |
[字符集合] | 匹配字符集合中任意一个字符 | '[tx]' 匹配任何包含 t 或 x 的字符串 | lt、xx |
[^] | 匹配不在字符集合中的文本 | '[^abc]' 匹配任何不包含 a、b 或 c 的字符串 | def、ghi |
{n,} | 匹配前面的字符串至少 n 次 | b{2} 匹配两个或更多的 b | bbb、bbbbbx |
{n, m} | 匹配前面的字符串至少 n 次,至多 m 次 | b{2, 4} 匹配含最少两个、最多四个 b 的字符串 | bxbxbx |
这个很好理解。
这个还搞不懂。
MySQL 使用 INSERT 语句向数据库表中插入数据,可以插入记录的一部分、插入完整的数据、插入多条记录、插入另一个查询的结果等。
2.1.1 为表的所有字段插入数据
INSERT INTO table_name (column_List) VALUES (value_List)
注意:字段列和数据列的数量必须相同,允许字段列表 column_List 为空,此时,值列表value_List 需要为表的每一个字段指定值,并且值的顺序必须和数据表中字段定义时的顺序一致。
2.1.2 为表的指定字段插入数据
指定部分字段值插入,未指定字段将取表定义时的默认值,如果未定义默认值,则为 NULL,但前提是未指定字段没有 NOT NULL 约束。
2.1.3 同时插入多条记录
INSERT INTO table_name (column_List) VALUES (value_List1), (value_List2), ..., (value_Listn)
使用 INSERT 同时插入多条记录时,MySQL 会返回一些在执行单行插入时没有的信息:
2.1.4 将查询结果插入到表中
INSERT INTO table_name1 (column_List1) SELECT (column_List2) FROM table_name2 WHERE (condition)
注意:column_List1 和 column_List2 的字段个数和数据类型必须相同。
MySQL 使用 UPDATE 语句更新数据库表中的数据。
UPDATE table_name SET column_name1 = value1, column_name2 = value2, ..., column_namen = valuen WHERE (condition)
注意:保证 UPDATE 语句以 WHERE 子句结束,通过 WHERE 子句指定被更新的记录所需满足的条件,如果忽略 WHERE 子句,MySQL 将更新表中所有的行。
从数据表中删除数据使用 DELETE 语句,DELETE 语句允许 WHERE 子句指定删除条件。
DELETE FROM table_name [WHERE <condition>]
注意:[WHERE <condition>] 为可选条件,如果没有 WHERE 子句,MySQL 将删除表中所有的行。如果想删除表中所有记录,还可以使用 TRUNCATE TABLE 语句,TRUNCATE 将直接删除原来的表,并重建一个表。其速度比 DELETE 快。
TRUNCATE TABLE table_name
计算列的值总是通过其它列或其它数据的值计算而来。
col_name data_type [GENERATED ALWAYS] AS (expression) [VIRTUAL | STORED] [UNIQUE [KEY]] [COMMENT comment] [NOT NULL | NULL] [[PRIMARY] KEY]
MySQL 8.0 中,CREATE TABLE 和 ALTER TABLE 中都支持增加计算列。
- mysql> CREATE TABLE tb54
- -> (
- -> id INT(9) NOT NULL AUTO_INCREMENT,
- -> a INT(9) DEFAULT NULL,
- -> b INT(9) DEFAULT NULL,
- -> c INT(9) GENERATED ALWAYS AS (a+b) VIRTUAL,
- -> PRIMARY KEY(`id`)
- -> );
- Query OK, 0 rows affected, 4 warnings (0.03 sec)
-
- mysql> SHOW WARNINGS;
- +---------+------+------------------------------------------------------------------------------+
- | Level | Code | Message |
- +---------+------+------------------------------------------------------------------------------+
- | Warning | 1681 | Integer display width is deprecated and will be removed in a future release. |
- | Warning | 1681 | Integer display width is deprecated and will be removed in a future release. |
- | Warning | 1681 | Integer display width is deprecated and will be removed in a future release. |
- | Warning | 1681 | Integer display width is deprecated and will be removed in a future release. |
- +---------+------+------------------------------------------------------------------------------+
- 4 rows in set (0.00 sec)
四个警告是说我们声明的数据类型只是做展示用,具体存储是多少位是不受此限制且不可预测的,但必然受到该数据类型的范围限制,这里不用管。
- mysql> INSERT INTO tb54(a, b) VALUES(11, 16), (21, 24);
- Query OK, 2 rows affected (0.01 sec)
- Records: 2 Duplicates: 0 Warnings: 0
-
- mysql> SELECT * FROM tb54;
- +----+------+------+------+
- | id | a | b | c |
- +----+------+------+------+
- | 1 | 11 | 16 | 27 |
- | 2 | 21 | 24 | 45 |
- +----+------+------+------+
- 2 rows in set (0.00 sec)
- mysql> UPDATE tb54 SET b = 17 WHERE id = 1;
- Query OK, 1 row affected (0.01 sec)
- Rows matched: 1 Changed: 1 Warnings: 0
-
- mysql> SELECT * FROM tb54;
- +----+------+------+------+
- | id | a | b | c |
- +----+------+------+------+
- | 1 | 11 | 17 | 28 |
- | 2 | 21 | 24 | 45 |
- +----+------+------+------+
- 2 rows in set (0.00 sec)
在 MySQL 8.0 中, InnoDB 表的 DDL 支持事务的完整性,即 DDL 要么成功要么失败回滚。DDL 操作的回滚日志写入到 data dictionary 数据字典表 mysql.innodb_ddl_log (该表是隐藏的表,通过SHOW TABLES 无法看到) 中,用于回滚操作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。