错位的梦寐

MySQL 查询执行顺序

2020-03-04


SQL 查询执行顺序

示例

SELECT DISTINCT t1.column1 AS alias1, t2.col2, aggregate_function(column3)
  FROM table1 t1
  JOIN table2 t1 ON t1.column1 = t2.column1
 WHERE conditions
 GROUP BY t1.column1, t2.col2
HAVING group_condition
 ORDER BY t1.column1 ASC, t2.col2 DESC
OFFSET m ROWS
 FETCH NEXT num_rows ROWS ONLY;

以上就是 SQL 语法中常见的各个子句(当然不是全部子句)的书写顺序,但是它们的逻辑执行顺序却与此不同:

  1. 首先,FROMJOIN是SQL执行的第一步,它们从逻辑上决定了接下来要操作的数据集;

  2. 其次,执行WHERE子句,对上一步的数据集进行过滤,保留满足条件的行;需要注意的是,此时还没有执行SELECT子句,WHERE条件中不能引用SELECT列表中的列别名(alias1)或者聚合函数
  3. 接下来,基于GROUP BY子句指定的表达式进行分组,分组条件有多少不同的取值,操作后的结果就有多少行;
  4. 然后,基于分组结果执行聚合函数 aggregate_function,对于每个分组取值,生成一个函数结果;如果没有分组子句,基于所有结果执行一次聚合操作;
  5. 如果查询中使用了GROUP BY,可以使用 HAVING对分组后的结果进一步进行过滤,通常是利用聚合函数的值进行过滤,如果是其他过滤条件,可以在WHERE子句中提前指定,避免无谓的操作;
  6. 接下来,SELECT子句可以选择要显示的列。如果存在GROUP BY子句,SELECT列表只能引用分组所使用的列,或者聚合函数;如果不存在GROUP BY子句,可以引用FROMJOIN指定的表中的任何列;
  7. 如果在SELECT之后指定了DISTINCT关键字,需要针对上一步的结果集进行去重操作,过滤掉所有重复的值;
  8. 应用ORDER BY子句对上一步的结果进行最终的排序操作。如果存在GROUP BY子句或者DISTINCT关键字,只能使用SELECT列表中出现的字段进行排序;如果不存在GROUP BY子句和DISTINCT,可以使用FROMJOIN指定的表中的任何列;
  9. 最后,OFFSETFETCH(或者LIMITTOP)限定了返回的行。

参考:

https://www.cnblogs.com/xiaohuochai/p/6081482.html


Comments

Content