3.7 DQL 语句
3.7.1 单表操作
语法:
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[SQL_CACHE | SQL_NO_CACHE]
select_expr [, select_expr ...]
[FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[FOR UPDATE | LOCK IN SHARE MODE]
说明:
-
字段显示可以使用别名:
- col1 AS alias1, col2 AS alias2, ...
-
WHERE 子句:指明过滤条件以实现"选择"的功能:
- 过滤条件:布尔型表达式
-
算术操作符:+, -, *, /, %
-
比较操作符:=,<=>(相等或都为空), <>, !=(非标准 SQL), >, >=, <, <=
-
BETWEEN min_num AND max_num,一般用于去范围条件
-
IN (element1, element2, ...),一般用于取几个条件也就是或者
-
IS NULL, IS NOT NULL,判断空值
-
DISTINCT 去除重复行,范例:SELECT DISTINCT gender FROM students;
-
LIKE: % 任意长度的任意字符 _ 任意单个字符
-
RLIKE:正则表达式,索引失效,不建议使用
-
REGEXP:匹配字符串可用正则表达式书写模式,同上
-
逻辑操作符:NOT,AND,OR,XOR
-
GROUP:根据指定的条件把查询结果进行"分组"以用于做"聚合"运算
- 常见聚合函数:avg(), max(), min(), count(), sum()
- HAVING: 对分组聚合运算后的结果指定过滤条件
- 一旦分组 group by ,select 语句后只跟分组的字段,聚合函数
-
ORDER BY: 根据指定的字段对查询结果进行排序
- 升序:ASC
- 降序:DESC
-
LIMIT [[offset,]row_count]:对查询的结果进行输出行数数量限制
-
对查询结果中的数据请求施加"锁
- FOR UPDATE: 写锁,独占或排它锁,只有一个读和写操作
- LOCK IN SHARE MODE: 读锁,共享锁,同时多个读操作
范例:密码生成
mariadb root@(none):(none)> select password("zhangzhuo");
+-------------------------------------------+
| password("zhangzhuo") |
+-------------------------------------------+
| *E537F5F82C1F36D566632B4C9061BD6715BABF7C |
+-------------------------------------------+
1 row in set
Time: 0.013s
范例:简单查询
范例:去重
mysql root@(none):hellodb> select distinct gender from students;
+--------+
| gender |
+--------+
| M |
| F |
+--------+
2 rows in set
Time: 0.008s
范例:分组统计
范例:分组和排序
3.7.2 多表查询
多表查询,即查询结果来自于多张表
-
子查询:在 SQL 语句嵌套着查询语句,性能较差,基于某语句的查询结果再次进行的查询
-
联合查询:UNION
-
交叉连接:笛卡尔乘积 CROSS JOIN
-
内连接:
- 等值连接:让表之间的字段以"等值"建立连接关系
- 不等值连接
- 自然连接:去掉重复列的等值连接 , 语法: FROM table1 NATURAL JOIN table2;
-
外连接:
- 左外连接:FROM tb1 LEFT JOIN tb2 ON tb1.col=tb2.col
- 右外连接:FROM tb1 RIGHT JOIN tb2 ON tb1.col=tb2.col
- 完全外连接: FROM tb1 FULL OUTER JOIN tb2 ON tb1.col=tb2.col 注意:MySQL 不支持此 SQL 语法
-
自连接:本表和本表进行连接查询
3.7.2.1 子查询
子查询 subquery 即 SQL 语句调用另一个 SELECT 子句,可以是对同一张表,也可以是对不同表,主要有以下四种常见的用法:
- 用于比较表达式中的子查询;子查询仅能返回单个值
用于 IN 中的子查询:子查询应该单独查询并返回一个或多个值重新构成列表
#查询学生表中年龄和老师表中年龄一致的
mysql root@(none):hellodb> select name,age from students where age in(select age from teachers);
- 用于 EXISTS 和 Not EXISTS
参考链接:https://dev.mysql.com/doc/refman/8.0/en/exists-and-not-exists-subqueries.html
EXISTS(包括 NOT EXISTS )子句的返回值是一个 BOOL 值。 EXISTS 内部有一个子查询语句(SELECT... FROM...), 将其称为 EXIST 的内查询语句。其内查询语句返回一个结果集。 EXISTS 子句根据其内查询语句的结果集空或者非空,返回一个布尔值。将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果为非空值,则 EXISTS 子句返回 TRUE,外查询的这一行数据便可作为外查询的结果行返回,否则不能作为结果
用于 FROM 子句中的子查询
使用格式:
SELECT tb_alias.col1,... FROM (SELECT clause) AS tb_alias WHERE Clause;
范例:
范例:子查询用于更新表
3.7.2.2 联合查询
联合查询 Union 实现的条件,多个表的字段数量相同,字段名和数据类型可以不同,但一般数据类型是相同的
SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers;
范例:联合查询
#多表联合查询,联合查询的表必须字段数相同
select tid as id,name,age,gender from teachers union select stuid,name,age,gender from students;
#如果是相同的表不会显示相同的信息
select * from teachers union select * from teachers;
#如果想显示相同的信息需要在union后面加all
select * from teachers union all select * from teachers;
范例:去重
#除去查询结果中的重复记录的distinct
select distinct * from teachers;
#联合查询默认是去重的union all不去重
3.7.2.3 交叉连接
cross join 即多表的记录之间做笛卡尔乘积组合,并且多个表的列横向合并相加, "雨露均沾"
比如: 第一个表 3 行 4 列,第二个表 5 行 6 列,cross join 后的结果为 3*5=15 行,4+6=10 列
交叉连接生成的记录可能会非常多,建议慎用
范例:交叉连接
#横向合并,交叉连接(横向笛卡尔)
#俩种写法
select * from students cross join teachers;
select * from students,teachers;
3.7.2.4 内连接
inner join 内连接取多个表的交集
范例:内连接
3.7.2.5 左和右外连接
范例:左,右外连接
3.7.2.6 完全外连接
MySQL 不支持完全外连接 full outer join 语法
3.7.2.7 自连接
自连接, 即表自身连接自身
范例:自连接
3.7.3 SELECT 语句处理的顺序
查询执行路径中的组件:查询缓存、解析器、预处理器、优化器、查询执行引擎、存储引擎
SELECT 语句的执行流程:
FROM Clause --> WHERE Clause --> GROUP BY --> HAVING Clause -->SELECT -->ORDER BY --> LIMIT
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于