在SQL中,据我所知,逻辑查询的处理顺序,也就是概念上的解释顺序,是以FROM开头的,方式如下:
- 从
- 在哪里
- 通过...分组
- 拥有
- 选择
- 订购方式
按照这个列表,很容易看出为什么不能在 WHERE 子句中使用 SELECT 别名,因为尚未创建别名。T-SQL (SQL Server) 严格遵循这一点,在通过 SELECT 之前不能使用 SELECT 别名。
但是在 MySQL 中,可以在 HAVING 子句中使用 SELECT 别名,即使它应该(逻辑上)在 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 都遵循的不同?
好吧,当您遇到此类问题时,恕我直言,最好的信息来源是 MySQL 文档。现在说到重点。
GROUP BY
这是默认启用的 MySql 扩展的行为。如果你想要标准行为,你可以禁用这个扩展
sql_mode
ONLY_FULL_GROUP_BY
如果您尝试在 sql_mode 中执行上述查询,
ONLY_FULL_GROUP_BY
您将收到以下错误消息:这是SQLFiddle演示
因此,如何配置和使用 MySQL 实例取决于您。
好问题。
我认为您应该运行这些查询
并检查查询是如何重写的。我很确定查询优化器将 Amount 替换为 COUNT(*)
就像它一样
在查询优化器之后是这样的。