(2022.04.13 Wed)
SQL是一种说明性语言(declarative language),也就是在SQL查询语句中,使用者需要查询出怎样的结果,而对于如何获取这些结果和数据,使用者无需指定。
SQL命令包括SELECT,WHERE,FROM等等语句,在输入DML命令被编译查询器(query compiler)处理后会分成操作序列。本文介绍的是命令的逻辑执行顺序(logical order)。注意,不同优化器(optimizer)在执行时未必完全按照逻辑顺序执行。
命令执行(逻辑)顺序
- FROM clause
- JOIN
- WHERE
- GROUP BY
- Aggregation function
- HAVING
- WINDOW FUNCTION
- SELECT
- DISTINCT
- UNION
- ORDER BY
- LIMIT and OFFSET
FROM
该指令限定了需要操作的数据对象。加载所有行数据并执行JOIN操作需要在做其他操作之前执行。需要再次强调,这是执行一个查询(或其他)命令的逻辑顺序,不同的优化器真实的处理顺序。比如有的优化器会访问WHERE语句中的索引。
WHERE
在FROM限定的数据对象基础之上,通过WHERE语句里的限定条件进一步缩小(narrow down/filter)选择范围。
WHERE语句的限定条件可以包括对FROM语句中涉及的数据和关系的引用,但不能包含对SELECT语句中定义的别名(aliase)的引用,因为SELECT语句还没有执行,其中的内容尚不在前后文中存在。
在WHERE语句中滤掉累加值(aggregated value)的操作会导致查询失败,比如WHERE SUM(some_value_field) > 1000
,因为累加操作在WHERE执行之前尚没有被执行。用累加数据作为条件筛选应该配合GROUP BY的HAVING语句而非WHERE语句。
GROUP BY
WHERE语句做数据的过滤之后,我们可以通过GROUP BY语句中给定的列来聚合数据(aggregate data)或分组。对数据做分组也就是把数据分成不同的块(chunk/bucket),每个块有一个键(key)和与键匹配的行。而不使用GROUP BY语句相当于把所有行放在一个巨大的块中。
Aggregation Function
数据分组完成,便可使用聚合函数返回每个分组的聚合值。聚合函数包括COUNT,MIN,MAX,SUM之类的。
HAVING
在对数据进行GROUP BY分组之后,我们使用HAVING语句对数据块进行过滤。HAVING语句中的条件可以引用聚合函数,所以前面WHERE语句中不能添加的聚合条件可以在HAVING语句中添加,HAVING SUM(some_value_field) > 1000
。
在数据GROUP BY之后就可以不再接入初始数据的所有行,仅对分组后的数据块做过滤且只对数据块而非数据行做过滤。
同时注意到,SELECT语句中定义的别名在这里也不能调用,因为还没有执行到SELECT语句。
WINDOW FUNCTION
窗口函数中使用了聚合函数,而聚合函数在前一步GROUP BY和HAVING命令中已经使用过,可被嵌入到窗口函数中(在窗口函数中引用聚合函数?),因为窗口函数的执行顺序在HAVING之后。和GROUP BY语句产生的结果不同,窗口函数的结果保留了被统计数据的所有行,GROUP BY则只产生一行数据。
同时也注意到,窗口函数不能用在WHERE语句中,可用于SELECT或ORDER BY语句中。
SELECT
终于系统开始执行用户查询命令的第一行SELECT语句。现在我们用前面语句生成的结果,创建/选出新的行/元组(tuple)。可以引用前面计算好的窗口函数、聚合函数、分组列,如果没做分组,也可以直接使用FROM语句中的所有列。
注意,在SELECT语句中出现的聚合函数,SUM/COUNT/MIN/MAX等,并非是在SELECT语句中得以计算,仅仅是对这些函数值的引用,因为这些值已经在GROUP BY语句之后和HAVING语句之前计算完成。
DISTINCT
尽管DISTINCT出现在SELECT语句中,但是它在SELECT语句之后得以执行。这很容易理解:只有在SELECT语句执行后,选出了所有需要的行和列之后,才可以对特定列的值去重。
UNION
该指令用于连接两个子查询。
ORDER BY
对数据的排序发生在对数据做过滤、分组、去重之后,这完全说得通。
一个特例是在做DISTINCT操作时,该指令会阻止对未选择的列做排序,这种情况下结果集的顺序未定义。(The ordering would be quite undefined.)
LIMIT & OFFSET
略。
Reference
1 learnsql点com: SQL Order of Operations
2 eversql点com: SQL order of operations - In which order MYSQL executes queries?
3 blog点jooq点org: A beginner's guide to the true order of SQL