SQL中的逻辑查询处理中的GROUP BY阶段返回什么?

时间:2013-11-08 12:34:30

标签: sql sql-server group-by sql-server-2012 having

在查询考试70-461的MS SQL Server 2012(培训套件)一书中,它说明了逻辑处理中查询的GROUP BY阶段:

  

此查询的最终结果有一行代表每个组   (除非过滤掉)。因此,所有阶段的表达都需要   在当前分组阶段之后的位置有些限制。所有   在后续阶段处理的表达式必须保证单个   每组价值。如果引用GROUP BY列表中的元素   (例如,国家),你已经有了这样的保证,所以这样的   允许引用。但是,如果要引用该元素   不属于GROUP BY列表(例如,empid),它必须是   包含在MAX或SUM等聚合函数中。那是因为   在单个组中的元素中可以有多个值,并且   保证只返回一个的唯一方法是   聚合价值观。

然后,作者提到HAVING步骤,他使用COUNT(*) > 1。我的问题是,如果GROUP BY每组只有1行的结果,HAVING阶段如何使用该单组行过滤掉任何超过1行的组...还有一半留在了吗?所以我在这里遗漏了一些东西。是否有某种隐藏的COUNT列附加到每个组?

查询是:

SELECT country, YEAR(hiredate) AS yearhired, COUNT(*) AS numemployees
FROM HR.Employees
WHERE hiredate >= '20030101'
GROUP BY country, YEAR(hiredate)
HAVING COUNT(*) > 1
ORDER BY country , yearhired DESC;

请启发。

1 个答案:

答案 0 :(得分:0)

如果作者在引用结果集的GROUP BY中引用每一组中的一行,那么当引用HAVING中每组的行时,他指的是输入。

想象一下这个简单的数据集

Col1    Col2    Value
----------------------
  a       a       1
  a       b       1
  a       b       1
  a       b       2
  a       c       1
  a       c       5

正如你所看到的,(Col1,Col2)有三个不同的元组 - (a,a),(a,b),(a,c),因此如果你是GROUP BY Col1,Col2你会得到三个结果中的行(每组一个)。

SELECT  Col1, Col2
FROM    T
GROUP BY Col1, Col2;

给出

Col1    Col2    
-------------
  a       a   
  a       b   
  a       c  

这是作者在说“每组一行”时所指的。

然而,再次扩展你可以看到有两行带有元组(a,b),两个用于(a,c) - 所以每个都有两个输入行,这就是{{1}是指,而不是结果集中的行数。

任何聚合函数(在有或在选择中)都与GROUP BY一起同时计算,而不是在它们各自的部分(HAVING,SELECT)。它们是相同的操作,这是它在选择或使用之前保持对组中行数的了解的方式。

Stackoverflow上的

There is very good answer解释了聚合如何在幕后工作以便进一步阅读,所以我在此不再重复。