考虑具有此结构的查询:
select ..., ROWNUM
from t
where <where clause>
group by <columns>
having <having clause>
order by <columns>;
据我了解,处理的顺序是
- FROM / WHERE子句首先出现 .
- ROWNUM被分配并递增到FROM / WHERE子句的每个输出行 .
3.应用GROUP BY .
4.应用HAVING .
5.应用ORDER BY .
6.应用SELECT .
我不明白为什么TOM的Oracle杂志中的this article规定:
将其视为按此顺序处理:
-
FROM / WHERE子句首先出现 .
-
ROWNUM被分配并递增到FROM / WHERE子句的每个输出行 .
-
SELECT已应用 .
-
GROUP BY已应用 .
-
HAVING已应用 .
-
ORDER BY已应用 .
谁能解释这个订单?
3 回答
SQL语句中的子句与处理顺序之间没有直接关系 . SQL查询分两个阶段处理 . 在第一阶段,编译和优化代码 . 运行优化版本 .
出于解析目的,将按特定顺序评估查询 . 例如,首先解析
FROM
,然后解析WHERE
,然后解析GROUP BY
,依此类推 . 这解释了为什么SELECT
中定义的列别名在FROM
中不可用 .但是,对于
ROWNUM
,您的描述不正确 .ROWNUM
是Oracle中的一个特殊构造 . . . 正如documentation中所述 . 它在ORDER BY
之前处理 .两个处理订单的唯一区别在于 "group by" 和 "select" 子句 . 我们可以用这个简单的例子解决这个问题
我有一个"emp"表,列"emp_id" . 现在让我在group by和select子句中给出不正确的列名,让我们先看看Oracle选择哪一个 .
错误返回
所以这证明 "group by" 在 "select" 之前被处理 . 希望这能清除你的怀疑 .
我认为不仅难以识别SQL语句的执行顺序,实际上这对您理解SQL有害 .
SQL是一种声明性语言,您可以在其中定义所需的结果,而不是实现该结果的方式(尽管可能会强烈影响该方式) . 我有很多被问到的经历,“那么这个SQL如何被执行?”开发人员更熟悉传统语言,事实上,SQL并没有告诉你这一点,期望非常简单的情况 . 一旦案例不简单,你就不能以“错误的方式”思考SQL .
它可能类似于面向对象语言和非面向对象语言之间的区别,或者功能编程和程序编程之间的区别 - 必然存在不同的思维方式 .
在SQL中,重点应该是理解语法及其如何定义结果集,然后理解数据库在其引用的模式的上下文中处理SQL的方式 .
我将专注于阅读关于该主题的Oracle Concepts Guide,这解释了提交给系统的查询经历了各个阶段(这是一个简单的概述):
解析
转型
估计
计划生成
执行
重要的是要意识到执行的SQL实际上可能不是您提交的SQL,但您可以使用各种开发人员工具深入了解所有这些阶段 .
这是一个非常不同的世界!