基础-SELECT的执行顺序及注意事项(重要知识)
1.基础数据
1.1.employee:
1.2.department:
1.3.查询结果
2.演示代码
# 如果是学习初期,不要被此代码吓到,后面会有详细解释,不懂之处可在进一步学习时巩固 WITH D AS (SELECT dept_id, dept_name FROM department WHERE dept_id<='1004') # 取出部门编号小于'1004'的部门编号及对应部门名称,形成表D(CTE表达式) SELECT ANY_VALUE(D.dept_id) AS dept_id, IF(GROUPING(D.dept_name),'汇总',D.dept_name) AS name, # 将WITH ROLLIP总计的组名改为汇总 COUNT(DISTINCT E.emp_name) AS dept_cnt, # 部门内员工去重计数 DENSE_RANK() OVER w-1 AS w_rank # 根据部门去重人数逆序排名并将排名-1(w1为命名窗口) FROM employee AS E LEFT JOIN D # 左外联接 ON E.dept_id=D.dept_id # 联接条件为部门编号 WHERE E.age BETWEEN 20 AND 50 # 筛选年龄在20-50岁的员工 GROUP BY D.dept_name WITH ROLLUP # 按部分分组,WITH ROLLUP总计 HAVING COUNT(DISTINCT E.emp_name)>=3 # 去重计数后员工数不小于3的部门保留 WINDOW w AS (ORDER BY COUNT(DISTINCT E.emp_name) DESC) # 窗口w的定义 ORDER BY GROUPING(D.dept_name) DESC,dept_cnt ASC # 先按照是否为总计行排序,再按部门人数升序 LIMIT 4; # 取出前四行 # 以上仅供演示所用,实际完成此查询未必需要如此操作
3.执行顺序
3.1.CTE
获得不含id='1005'的记录的临时表D
3.2.FROM
2.1对表E和表D进行交叉联接,形成虚拟表VT-J1
2.2.根据ON条件筛选满足条件的行,形成VT-J2
2.3.由于LEFT JOIN,需要保留在表E中不满足筛选条件的行,形成VT-J3
获得所有员工信息及对应的部门信息的虚拟表VT-J
3.3.WHERE
筛选年龄在20-50岁的记录,形成虚拟表VT-WH
3.4.GROUP BY
4.1.按照部门信息分组,组名就是部门名(dept_name为NULL的所有记录为一组,组名为NULL),形成虚拟表VT-G1
4.2.由于WITH ROLLUP,还需要新增总计行,组名为NULL,形成虚拟表VT-G2
获得按部门分组后的虚拟表VT-G
3.5.HAVING
筛选部门的不重复员工总数不少于3的分组,形成虚拟表VT-H
注意1:组名为NULL的分组因不重复员工数为3而被保留
注意2:组名为NULL的总计行因不重复员工数为19而被保留(总计行计算的是VT-WH的所有非重复员工数,不区分部门)
3.6.SELECT
保留部门编号,部门名称,各部门不重复员工数,形成虚拟表VT-S
注意1:由于dept_id既不是分组列也并非聚合列,因此直接引用会报错,此处使用ANY_VALUE可正确引用
注意2:此处想仅给总计行重命名为'汇总',使用GROUPING判断是否为总计行,如果是则重命名,否则保持原名
3.7.WINDOW
将各部门不重复员工数逆序作为窗口进行密集排名,将排名值减一作为实际排名,将该排名列加入VT-S,形成虚拟表VT-WI
注意1:此步骤虽基于VT-S,但因处在SELECT中无法用dept_cnt替代COUNT(DISTINCT E.emp_name)
注意2:事实上,窗口函数是上下文相关的(请参考专栏内基础-窗口函数章节)
3.8.ORDER BY
先根据是否为总计行(是则为1,否则为0)逆序(即总计行排至第一行),再根据部门的不重复人数升序,形成虚拟表VT-O
3.9.LIMIT
输出VT-O中的前4行
4.总结
了解SELECT语句的执行顺序是非常重要的,如果缺少了解,在面对较复杂的查询时可能首先会被语法错误绊倒,此文较为详细全面的展示了每个组成部分的执行顺序及注意要点,其中很多内容在学习初期可能未涉及,可随着学习的深入不断加深理解,部分内容可参考专栏其他文章
更多知识见专栏
#SQL菜鸟#阅读顺序为:入门->基础(务必阅读,尤其是SELECT语句的执行顺序)->进阶->应用(综合使用)。 这是一部较为系统的大纲式SQL查询教程,学习过程中应同步参考官方文档或其他相关资料,交叉阅读方能更好掌握知识,学会后基本可以完成站内90%以上的相关试题。 DDL及DML的其他内容后续更新。 如有帮助请您点赞收藏订阅,如有疑惑或指正请评论。 共同学习共同进步!