面试题:SQL中SELECT语句执行顺序
前置知识
SQL中 SELECT
语句的语法结构
SELECT DISTINCT <select_list>,AGGREGATE_FUNCTION(column_name or expression), ...
FROM <left_table> <join_type> JOIN <right_table> ON <join_condition>
WHERE <where_condition>
GROUP BY <group_by_list>
WITH CUBE | ROLLUP
HAVING <having_condition>
ORDER BY <order_by_condition> LIMIT <limit_number> OFFSET <offset_number>;
其中需要的注意点:
- GROUP BY 有一个原则,就是 SELECT 后面的所有列中,没有使用聚合函数(AGGREGATE_FUNCTION)的列,必须出现在 GROUP BY 后面
- WHERE 子句的作用是在对查询结果进行分组前,将不符合 WHERE 条件的行过滤掉,同时需要注意的是 WHERE 子句条件中不能包含聚合函数
- HAVING 子句的作用是在分组后筛选满足条件的组,条件中经常包含聚合函数
- LIMIST 字句中 OFFSET 作用是指定要返回的第一行的偏移量,同时第一行的偏移量为0,而不是1
SELECT语句 - 执行顺序
(9) SELECT (10) DISTINCT <column_name>,
(6) AGGREGATE_FUNCTION(column_name or expression), ...
(1) FROM left_table
(3) JOIN right_table
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(7) WITH CUBE | ROLLUP
(8) HAVING constraint_expression
(11) ORDER BY <order_by_condition>
(12) LIMIT <limit_number> OFFSET <offset_number>;
执行顺序说明:
- FROM:选取表,将多个表的数据通过笛卡尔积连成一张虚表 VT1
- ON:对笛卡尔积的虚表 VT1 进行条件筛选形成虚表 VT2
- JOIN:根据 JOIN 类型,在虚表 VT2 的基础上添加保留表中被过滤条件过滤掉的数据,非保留表中的数据被赋予 NULL 值,形成虚表 VT3
- WHERE:对虚表 VT3 进行条件筛选,把满足条件的数据插入虚表 VT4
- GROUP BY**:根据分组条件将虚表 VT4 的行唯一的值合成一组,生成虚表 VT5
- AGGREGATE_FUNCTION:聚合函数的计算,比如 MIN、MAX、AVG、COUNT、SUM
- WITH 应用 ROLLUP 或 CUBE:对虚表 VT5 应用 ROLLUP 或 CUBE 选项,生成虚表 VT6
- CUBE 生成的结果数据集显示了所选列中值的所有组合的聚合
- ROLLUP 生成的结果数据集显示了所选列中值的某一层次结构的聚合
- HAVING(HAVING过滤聚合值):对虚表 VT6 应用 HAVING 筛选器。根据指定的条件对数据进行筛选,并把满足的数据插入虚表 VT7
- SELECT:将虚表 VT7 中的在 SELECT 中出现的列筛选出来,并对字段进行处理,计算 SELECT 子句中的表达式,产生虚表 VT8
- DISTINCT:将重复的行从虚拟表 VT8 中移除,产生虚拟表 VT9。DISTINCT 用来删除重复行,只保留唯一的
- ORDER BY:将虚表 VT9 中的行按 ORDER BY 子句中的条件排序,生成游标 VC10 ;此时返回的一个游标,而不是虚表
- LIMIT/OFFSET:从 VC10 的 开始处(offset_number) 选择 指定数量行(limit_number),生成虚表 VT11,并返回调用者