2011-01-27 65 views
3

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

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

因为SELECT条款执行HAVING条款后,所以当引擎读取HAVING条款,不知道的还什么CountById手段。

+0

有道理,你知道是否有办法完成同样的想法?不得不重复这样的混合功能,在我的嘴里留下不好的味道。 – asawyer 2011-01-27 15:28:53

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

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

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
1

通常SELECT列表进行评估的声明的最后一部分(即使它是第一部分!),所以没有办法在语句的其他子句中使用定义的别名。