SQL聚合和别名

时间:2011-01-27 15:21:11

标签: sql

如果表中多次引用该项,我有一个需要返回标量值的查询。

SELECT 
    COUNT(*)
FROM 
    Items
WHERE
    FKID = 2003799
GROUP BY 
    FKID 
HAVING 
    COUNT(*)>1 
ORDER BY 
    COUNT(*)

为什么我不能为aggragate分配别名,并在查询的其余部分引用别名而不是重复aggragate函数?

类似的东西:

SELECT 
    COUNT(*) AS CountById
FROM 
    Items
WHERE
    FKID = 2003799
GROUP BY 
    FKID 
HAVING 
    CountById>1 
ORDER BY 
    CountById

编辑 - 是否存在允许相同想法的替代语法?

4 个答案:

答案 0 :(得分:3)

基本上,答案是......最后解释SELECT列表......这里基本上是顺序...请参阅http://databases.aspfaq.com/database/how-do-i-use-a-select-list-alias-in-the-where-or-group-by-clause.html

  1. 从FROM子句开始,从所有连接,联合,交集以及其他任何表构造函数构建工作表。 AS选项允许您为此工作表指定一个名称,然后您必须将该名称用于包含查询的其余部分。

  2. 转到WHERE子句并删除未通过条件的行;也就是说,不测试为TRUE(拒绝UNKNOWN和FALSE)。 WHERE子句适用于FROM子句中的工作。

  3. 转到可选的GROUP BY子句,创建组并将每个组缩减为一行,将原始工作表替换为新的分组表。分组表的行必须是组特征:(1)分组列(2)关于组的统计(即聚合函数)(3)函数或(4)由这三个项组成的表达式。

  4. 转到可选的HAVING子句并将其应用于分组工作表;如果没有GROUP BY子句,则将整个表视为一个组。

  5. 转到SELECT子句并在列表中构造表达式。这意味着SELECT中的标量子查询,函数调用和表达式在完成所有其他子句之后完成。 AS运算符也可以为SELECT列表中的表达式命名。这些新名称一下子就存在了,但是在WHERE子句执行之后;由于这个原因,你不能在SELECT列表或WHERE cluase中使用它们。

  6. 嵌套查询表达式遵循您期望的块结构化语言(如C,Pascal,Algol等)的常规作用域规则。即,最里面的查询可以引用包含它们的查询中的列和表。

答案 1 :(得分:1)

原因与查询的处理顺序有关。在GROUP BY处理之前评估HAVINGSELECT,因此您的别名在此时未定义。另一方面,在ORDER BY之后处理SELECT,因此您的列别名在那里有效。

Pinal Dave's Blog开始,评估顺序为:

  1. FROM
  2. ON
  3. OUTER
  4. WHERE
  5. GROUP BY
  6. CUBE | ROLLUP
  7. HAVING
  8. 选择
  9. DISTINCT
  10. ORDER BY
  11. TOP

答案 2 :(得分:1)

通常SELECT列表是要评估的语句的最后一部分(即使它是第一部分!)因此无法在语句的其他子句中使用在那里定义的别名。

答案 3 :(得分:0)

因为SELECT子句在<{strong> HAVING子句后执行,所以当引擎读取HAVING子句时,它还不知道是什么{ {1}}表示。