据我所知,在SQL中,逻辑查询处理顺序(即概念解释顺序)以以下方式从FROM开始:
- 从
- 哪里
- 通过...分组
- 拥有
- 选择
- 订购
在此列表之后,很容易看出为什么在WHERE子句中没有SELECT别名,因为尚未创建别名。T-SQL(SQL Server)严格遵循此原则,在传递SELECT之前,您不能使用SELECT别名。
但是在MySQL中,即使应该(在逻辑上)在SELECT子句之前对其进行处理,也可以在HAVING子句中使用SELECT别名。这怎么可能?
举个例子:
SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING Amount>1;
该语句在T-SQL中无效(因为HAVING引用了SELECT别名Amount
)...
Msg 207, Level 16, State 1, Line 5
Invalid column name 'Amount'.
...但是在MySQL中工作正常。
基于此,我想知道:
- MySQL是否在SQL规则中采取捷径来帮助用户?也许使用某种预分析?
- 还是MySQL使用的概念解释顺序与我遵循的所有RDBMS遵循的顺序不同?
1
我的猜测是,这是您的第二点。
—
a_horse_with_no_name
好吧,我想除非它们支持排名功能,否则不会引起任何歧义或混淆。然后
—
马丁·史密斯
SELECT C, ROW_NUMBER() OVER (ORDER BY X) AS RN FROM T GROUP BY C HAVING RN = 1
将问题的,因为ROW_NUMBER
运行后的HAVING
我不确定MySQL支持哪些排序功能。如果您想要行号,则必须以这种方式创建它:
—
Ohlin
SELECT @rownum:=@rownum + 1 as row ...
。也许它们之所以支持SELECT别名的原因仅仅是因为它们可以,因为它们不支持使之成为不可能的事情……谁知道呢?:)
正如@MartinSmith解释的那样,只要没有窗口/排序功能,就可以互换
—
ypercubeᵀᴹ
HAVING
and SELECT
子句的逻辑执行顺序。因此,这样做没有任何歧义,并且当中存在怪异的表达式时,可以简化代码的外观SELECT
。