如果表中多次引用该项,我有一个需要返回标量值的查询。
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
编辑 - 是否存在允许相同想法的替代语法?
答案 0 :(得分:3)
基本上,答案是......最后解释SELECT列表......这里基本上是顺序...请参阅http://databases.aspfaq.com/database/how-do-i-use-a-select-list-alias-in-the-where-or-group-by-clause.html。
从FROM子句开始,从所有连接,联合,交集以及其他任何表构造函数构建工作表。 AS选项允许您为此工作表指定一个名称,然后您必须将该名称用于包含查询的其余部分。
转到WHERE子句并删除未通过条件的行;也就是说,不测试为TRUE(拒绝UNKNOWN和FALSE)。 WHERE子句适用于FROM子句中的工作。
转到可选的GROUP BY子句,创建组并将每个组缩减为一行,将原始工作表替换为新的分组表。分组表的行必须是组特征:(1)分组列(2)关于组的统计(即聚合函数)(3)函数或(4)由这三个项组成的表达式。
转到可选的HAVING子句并将其应用于分组工作表;如果没有GROUP BY子句,则将整个表视为一个组。
转到SELECT子句并在列表中构造表达式。这意味着SELECT中的标量子查询,函数调用和表达式在完成所有其他子句之后完成。 AS运算符也可以为SELECT列表中的表达式命名。这些新名称一下子就存在了,但是在WHERE子句执行之后;由于这个原因,你不能在SELECT列表或WHERE cluase中使用它们。
嵌套查询表达式遵循您期望的块结构化语言(如C,Pascal,Algol等)的常规作用域规则。即,最里面的查询可以引用包含它们的查询中的列和表。
答案 1 :(得分:1)
原因与查询的处理顺序有关。在GROUP BY
处理之前评估HAVING
和SELECT
,因此您的别名在此时未定义。另一方面,在ORDER BY
之后处理SELECT
,因此您的列别名在那里有效。
从Pinal Dave's Blog开始,评估顺序为:
答案 2 :(得分:1)
通常SELECT
列表是要评估的语句的最后一部分(即使它是第一部分!)因此无法在语句的其他子句中使用在那里定义的别名。
答案 3 :(得分:0)
因为SELECT
子句在<{strong> HAVING
子句后执行,所以当引擎读取HAVING
子句时,它还不知道是什么{ {1}}表示。