数据库中的SELECT语句逻辑执行顺序分析

本文解析了SQL中SELECT语句的逻辑执行顺序,并通过具体示例说明了常见错误及其原因,有助于理解并优化SQL查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇文章主要介绍了数据库中的SELECT语句逻辑执行顺序分析,并列出了一些例子,需要的朋友可以参考下

引言

  这不是一个什么多深的技术问题,多么牛叉的编程能力。这跟一个人的开发能力也没有非常必然的直接关系,但是知道这些会对你的SQL编写,排忧及优化上会有很大的帮助。它不是一个复杂的知识点,但是一个非常基础的SQL根基。不了解这些,你一直用普通水泥盖房子;掌握这些,你是在用高等水泥盖房子。

  然而,就是这么一个小小的知识点,大家可以去调查一下周围的同事朋友,没准你会得到一个“惊喜”。

  由于这篇文章是突然有感而写,下面随手编写的SQL语句没有经过测试。

  看下面的几段SQL语句:

复制代码代码如下:
#1
SELECT ID,COUNT(ID) AS TOTAL
 
FROM STUDENT
 
GROUP BY ID
 
HAVING TOTAL>2
#2
SELECT ID,COUNT(ID) AS TOTAL
 
FROM STUDENT
 
GROUP BY ID
 
ORDER BY TOTAL
#3
SELECT FIRSTNAME+' '+LASTNAME AS NAME, COUNT(*) AS COUNT
 
FROM STUDENT
 
GROUP BY NAME

你觉得哪一个不能够成功执行?

下面是SELECT语句的逻辑执行顺序:

1.FROM
2.ON
3.JOIN
4.WHERE
5.GROUP BY
6.WITH CUBE or WITH ROLLUP
7.HAVING
8.SELECT
9.DISTINCT
10.ORDER BY
11.TOP
  MICROSOFT指出,SELECT语句的实际物理执行顺序可能会由于查询处理器的不同而与这个顺序有所出入。

几个示例

示例一:

复制代码代码如下:

SELECT ID,COUNT(ID) AS TOTAL
 
FROM STUDENT
 
GROUP BY ID
 
HAVING TOTAL>2

觉得这个SQL语句眼熟吗?对,非常基础的分组查询。但它不能执行成功,因为HAVING的执行顺序在SELECT之上。

实际执行顺序如下:

1.FROM STUDENT
2.GROUP BY ID
3.HAVING TOTAL>2
4.SELECT ID,COUNT(ID) AS TOTAL
  很明显,TOTAL是在最后一句SELECT ID,COUNT(ID) AS TOTAL执行过后生成的新别名。因此,在HAVING TOTAL>2执行时是不能识别TOTAL的。

示例二

复制代码代码如下:

SELECT ID,COUNT(ID) AS TOTAL
 
FROM STUDENT
 
GROUP BY ID
 
ORDER BY TOTAL

这个的实际执行顺序是:

1.FROM STUDENT
2.GROUP BY ID
3.SELECT ID,COUNT(ID) AS TOTAL
4.ORDER BY TOTAL
  这一次没有任何问题,能够成功执行。如果把ORDER BY TOTAL换成ORDER BY COUNT(ID)呢?

复制代码代码如下:

SELECT ID,COUNT(ID) AS TOTAL
 
FROM STUDENT
 
GROUP BY ID
 
ORDER BY COUNT(ID)

实际执行顺序:

1.FROM STUDENT
2.GROUP BY ID
3.SELECT ID,COUNT(ID) AS TOTAL
4.ORDER BY COUNT(ID)

  没错,它是能够成功执行的,看SQL执行计划,它与上面ORDER BY TOTAL是一样的。ORDER BY 是在SELECT后执行,因此可以用别名TOTAL。

示例三

复制代码代码如下:

SELECT FIRSTNAME+' '+LASTNAME AS NAME, COUNT(*) AS COUNT
 
FROM STUDENT
 
GROUP BY NAME

 实际执行顺序:

复制代码代码如下:

FROM STUDENT
 
GROUP BY NAME
 
SELECT FIRSTNAME+' '+LASTNAME AS NAME,COUNT(*) AS COUNT

很明显,执行GROUP BY NAME时别名NAME还没有创建,因此它是不能执行成功的。

总结

  回忆起曾经随意问过一些人这个问题,不管谁说不知道时我们都会故意嘲笑一翻,当然此嘲笑非彼嘲笑。但事实证明还是有一些人不会注意到这个知识点,在此贴出来只是做为一个友好的提醒。


### SQL SELECT 语句逻辑处理顺序 SQL 查询语句的实际执行顺序并不完全按照书写顺序进行,而是遵循一定的逻辑处理流程。以下是 SQL 中 `SELECT` 表达式的逻辑执行顺序: 1. **FROM 子句** 首先从数据源表或视图中获取基础数据集。这是整个查询的基础部分[^3]。 2. **ON 子句** 如果存在连接操作(JOIN),则通过 ON 条件指定如何匹配左表和右表中的记录[^4]。 3. **JOIN 子句** 根据 JOIN 类型(如 INNER JOIN、LEFT JOIN 等)以及 ON 条件的结果构建中间结果集。 4. **WHERE 子句** 对 FROM 和 JOIN 后产生的中间结果应用过滤条件,仅保留满足 WHERE 谓词的行[^2]。 5. **GROUP BY 子句** 将经过 WHERE 过滤后的结果分组,以便后续聚合函数能够作用于每组数据上。 6. **HAVING 子句** 在完成分组之后进一步筛选符合条件的组,类似于 WHERE 的功能但针对已分组的数据。 7. **SELECT 子句** 定义最终输出列的内容及其别名设置;此时可以选择字段或者调用各种内置函数来转换原始数据。 8. **DISTINCT 关键字** 去除重复项以确保结果集中每一行都是唯一的。 9. **ORDER BY 子句** 按照指定的一个或多列对结果集排序,默认升序排列。 10. **LIMIT/TOP 子句** 控制返回的最大行数或百分比,从而减少不必要的大数据量传输。 需要注意的是上述过程描述了一个理论上的“逻辑执行路径,在实际数据库引擎内部可能会因为性能优化等原因调整物理执行计划,但这不影响理解标准 SQL 查询的工作机制。 ```sql -- 示例代码展示完整的 SQL 查询结构 SELECT DISTINCT column_name, COUNT(*) FROM table_name INNER JOIN another_table ON table_name.id = another_table.foreign_id WHERE condition_expression GROUP BY column_name HAVING aggregate_function(condition) ORDER BY sort_column ASC/DESC LIMIT number_of_rows; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值