用一条复杂的语句记录顺序:
1 | (7) SELECT |
解析:
- FROM: 对 FROM 的左边的表和右边的表计算笛卡尔积。产生虚表 VT1
- ON: 对虚表 VT1 进行 ON 筛选,只有那些符合
<join-condition>
的行才会被记录在虚表VT2中。 - JOIN: 如果指定了 OUTER JOIN(比如 left join、right join),那么保留表中未匹配的行就会作为外部行添加到虚拟表 VT2 中,产生虚拟表 VT3, rug from 子句中包含两个以上的表的话,那么就会对上一个 join 连接产生的结果 VT3 和下一个表重复执行步骤 1~3 这三个步骤,一直到处理完所有的表为止。
- WHERE: 对虚拟表 VT3 进行 WHERE 条件过滤。只有符合
<where-condition>
的记录才会被插入到虚拟表 VT4 中。 - GROUP BY: 根据 group by 子句中的列,对 VT4 中的记录进行分组操作,产生 VT5.
- CUBE | ROLLUP: 对表 VT5 进行 cube 或者 rollup 操作,产生表 VT6.
- HAVING: 对虚拟表 VT6 应用 having 过滤,只有符合
<having-condition>
的记录才会被插入到虚拟表 VT7 中。 - SELECT: 执行 select 操作,选择指定的列,插入到虚拟表 VT8中。
- DISTINCT: 对 VT8 中的记录进行去重。产生虚拟表 VT9.
- ORDER BY: 将虚拟表 VT9 中的记录按照
<order_by_list>
进行排序操作,产生虚拟表 VT10. - LIMIT:取出指定行的记录,产生虚拟表 VT11, 并将结果返回。
另外需要注意的问题:
(1) GROUP BY 存在时,SELECT 中除了聚集函数外,所有的基本列必须是 GROUP BY 里面存在的。参见 《SQL_MODE = ONLY_FULL_GROUP_BY》
(2) HAVING 基本上同 GROUP BY 一起使用的,HAVING 类似于 WHERE 语句,只是 HAVING 过滤是基于 GROUP BY 分组后的数据,HAVING 一般通过 SELECT 语句里面的聚集函数进行过滤。