记录一个奇怪的现象(SQL 的执行顺序)

SQL 的一般逻辑执行顺序是:


1. FROM 和 JOIN

首先从 FROM 和 JOIN 中的表中选取数据。

2. WHERE

然后应用 WHERE 进行过滤。

3. GROUP BY

接着进行 GROUP BY 分组。

4. HAVING

HAVING 会再基于 GROUP BY 的结果进行过滤。

5. SELECT

然后执行 SELECT 选择需要的列。

> 如果在 `SELECT` 子句中使用了聚合函数,如 `SUM()` 或 `AVG()`,那么这些函数会在这个步骤中被应用于由 `GROUP BY` 子句定义的每个分组。

6. DISTINCT

会排除重复列。

7. ORDER BY

最后是 ORDER BY 排序。


所以一个典型的 SQL 查询执行顺序是:

FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT -> ORDER BY


简单总结:

- FROM 和 JOIN 获得原始数据

- WHERE 初步过滤

- GROUP BY 分组

- HAVING 过滤分组

- SELECT 选择列

- DISTINCT 去重

- ORDER BY 排序


当然,数据库查询优化器会根据查询计划调整具体的执行顺序,但这个顺序表达了 SQL 各子句的逻辑关系。


---

记录一个奇怪的现象:


```mysql

select

EventName name,

sum(Duration) total_duration

from events

where EventName = '事件1'

group by name;

```


以上查询语句是对的,把 group by 的 name 换成原字段名 EventName 也是对的,在 DataGrip 中不会报错,也能正常运行。



如果是这样,那上图注释中的第一条论断就不准确了,也与 SQL 的一般执行顺序冲突。


我先后问了 Claude、GPT3.5、GPT4,首次得到的答案都说是 group by 在 select 之前执行!!!


当我拿着以上反例质疑时,Claude 马上承认了 “错误”,并表示学到了新知识,做出了 “改正”,而 GPT3.5 和 GPT4 虽然承认了 “错误”,但在新的答案中却没有 “改正”,一副知错不改的模样。


综合以上信息,再结合我自己的逻辑推断,它们第一次的答案很可能是对的,group by 就是在 select 之前执行!而在这个例子中 group by 之所以能应用 select 的别名 name,很可能是 DataGrip 或 SQL 的容错或优化,与实际执行顺序没有太大的关系。


或许不能简单的根据是否能应用别名来判断执行顺序。

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
沐风
下载 APP