一文读懂SQL查询语句执行顺序丨全解析

说实话,SQL执行顺序的解释还是很清楚的,但是光看文字可能会有点混乱。
我举一个小例子,可能更直观。

比如我想查个东西:我想查看纽约部门工资大于5 000的员工,需要统计每个部门有多少人。
人数应该在1 0人以上,最后我想按照人数降序排序,只看到前5 个部门。

SQL 选择 d.name, COUNT(e.id) 作为员工计数 来自员工 连接部门 d ON e.dept_id = d.id WHERE e.salary > 5 000 且 d.location = '纽约' d.按名称分组 如果计数 (e.id) > 1 0 按员工计数 DESC 排序 限制5
这行代码是如何运行的呢?
如果你想一下,你首先需要从员工和部门表中提取数据。
连接时,行将根据 dept_id 对齐。
此步骤与FROM/JOIN相同。
生成的临时表中的每一行对应一个员工,可以知道他或她属于哪个部门。

然后 WHERE 开始过滤并删除所有不在纽约或工资不超过 5 ,000 美元的行。
请注意,此时您无法使用 SUM(),因为它尚未分组。

接下来,GROUP BY d.name 按部门名称进行分组,现在每个部门合并为一行。
例如,在纽约,部门被集中在一起,其他部门也被组织成小组。
已完成
count(e.id) > 从 1 0 开始筛选组,这意味着每个组必须有 1 0 名以上员工,不足的将被踢出。
只有在分组完成后才能使用聚合函数。

然后SELECT选择部门名称和人数。
人数通过COUNT(e.id)计算。
请注意,此计数发生在分组之后,并且每组计数一次。

最后 ORDER BY employee_count DESC 将结果按人数降序排序,LIMIT 5 只保留前 5 个部门。

有趣的是,这个顺序实际上与书面顺序有很大不同。
例如,WHERE实际上是在GROUP BY之前执行的,但是写的时候,WHERE是在GROUP BY之前。
这可能会令人困惑,尤其是对于新手来说。
刚开始学习的时候,总是会发现错误,必须结合例子反复思考。

还有一个细节需要注意。
例如,如果您使用 DISTINCT,例如 SELECT DISTINCT d.name,则重复项将被删除。
但这个去重是在执行SELECT的时候完成的,也就是说前面的步骤都已经完成了,重复的行最终被删除了。
这一步可能会比较慢,尤其是数据量很大的时候,所以是否可以使用要看情况。

理解这个序列确实可以帮助人们优化SQL。
例如,不要向后拖动 WHERE 过滤器,这会导致稍后处理数据。
数量可能会少一些。
像我上面的例子,如果不先用WHERE过滤,分组后再过滤,那么每次group by都得扫描整个表,肯定会很慢。
而如果在WHERE中使用聚合函数,这就更加禁止,会报错,因为WHERE只能使用非聚合条件。

简而言之,熟能生巧。
多读几次例子你就会明白了。

图解 SQL 执行顺序,通俗易懂!

告诉你一件事,我去年在一家公司工作,那段时间我真的很担心写SQL。

我记得有一次,我要检查两张表,一张是员工表,一张是工资表。
我必须使用SQL连接这两个表来检查每个员工的工资。
我用from写了这两个表的名字,然后join的时候选择了inner join,只检查两个表匹配的数据。
还需要加上一个where,比如where员工表.id = 工资表.员工id,这样就不会找到一堆乱七八糟不相关的数据,不然就是笛卡尔积了,你都不知道是什么。

后来领导说,要把员工按照部门分组,看看每个部门的平均工资等等。
我按部门 ID 添加了一个组。
请注意,group by 表示分组,而不是过滤。
不要将它与地点混淆。

你必须使用必须过滤。
where 在分组之前使用来过滤单个记录。
但having就是对分组后的结果进行过滤。
例如,having avg (salary) < 5>有时你会发现,如果将 where 条件移至having,SQL 语句看起来就顺眼多了。

分组后,您仍然需要选择要显示的内容。
我用select进行聚合,比如选择部门id,avg(工资)作为平均工资。
有时候表中存在同名的字段,就得用as给它们起别名,否则显示的都一样,会很混乱。

最后,我们应该如何排序呢? 按照平均工资的降序排列,我将按平均工资 desc 添加顺序。
如果领导说只看前三名,那就在最后加上限制3 记住,limit一定要放在最后,否则查到的数据可能不正确。
比如要查成绩最小的三个学生,必须先按年级asc排序,然后限制3 个,这样才准确。

你看,只要一步步来,写SQL并不难。
关键是要了解每个步骤的作用。
大家可以看一下之前几期的文章,写的很详细。
它们也将有助于优化和其他事情。

一张图看懂sql运行顺序

记得有一次,我在公司的一个小团队中负责优化一个复杂的SQL查询。
这是一个关于销售数据的查询,涉及多个表,包括JOIN、WHERE、GROUP BY和HAVING。
我坐在电脑前,盯着屏幕,试图理解查询的每一行代码。

突然我意识到,如果先从WHERE子句开始优化,可能会减少后面处理的数据量,提高查询效率。
于是,我调整了查询​​语句,将WHERE子句中的条件提前,发现查询时间从原来的3 0秒缩短到了1 0秒。
这个小小的改变让我对SQL查询优化有了更深入的了解。

等等,还有别的事。
突然想到如果结合索引的使用,效果可能会更好。
不过,我得等到下次再尝试这个。