SQL Server 无法“识别”COUNT 的别名

And*_*rei 6 sql-server

我已经使用 SQL Server 从备份文件恢复了 Northwind 数据库(https://northwinddatabase.codeplex.com/)。

尝试执行以下查询会导致错误“无效的列名 'products'。”,product 是别名。

SELECT OrderID, COUNT(ProductID) products
FROM [NORTHWND].[dbo].[OrderDetails]
GROUP BY OrderID
HAVING products > 5;
Run Code Online (Sandbox Code Playgroud)

问题是什么?

Jul*_*eur 22

SELECT子句后逻辑处理HAVING子句。因此,在处理子句SELECT时,使用的别名(还)不存在HAVING

在 MSDN 上,您可以查看SELECT (Transact-SQL)

SELECT 语句的逻辑处理顺序

以下步骤显示了 SELECT 语句的逻辑处理顺序或绑定顺序。此顺序决定了在一个步骤中定义的对象何时可用于后续步骤中的子句。例如,如果查询处理器可以绑定(访问)在 FROM 子句中定义的表或视图,则这些对象及其列可用于所有后续步骤。相反,由于 SELECT 子句是第 8 步,因此该子句中定义的任何列别名或派生列都不能被前面的子句引用。但是,它们可以被后续子句引用,例如 ORDER BY 子句。请注意,语句的实际物理执行由查询处理器确定,并且顺序可能与此列表不同。

  1. 加入
  2. 在哪里
  3. 通过...分组
  4. WITH CUBE 或 WITH ROLLUP
  5. 选择
  6. 清楚的
  7. 订购者
  8. 最佳

此查询有效,因为它重复了稍后将COUNTSELECT子句中定义的内容 (the ) :

SELECT OrderID, COUNT(ProductID) products
FROM [NORTHWND].[dbo].[OrderDetails]
GROUP BY OrderID
HAVING COUNT(ProductID) > 5;
Run Code Online (Sandbox Code Playgroud)

  • +1。令人惊讶的是,即使是官方文档也没有完全正确(好吧,不是那么令人惊奇,但对于 MSDN 来说很常见。它的某些部分写得很笨拙并且省略了细节)。`JOIN` 和 `ON` 是 `FROM` 子句的一部分,而不是文章暗示的独立子句。 (2认同)

Aar*_*and 7

因为HAVING是在列表中生成别名之前解析的SELECT此处详细解释了这一点

唯一可以使用别名的地方是在ORDER BY子句中。解决方法是重复 中的表达式HAVING

    SELECT OrderID, COUNT(ProductID) AS Products
      FROM Northwind.dbo.OrderDetails
      GROUP BY OrderID
      HAVING COUNT(ProductID) > 5;
Run Code Online (Sandbox Code Playgroud)