【问题标题】:What does the GROUP BY phase in logical query processing in SQL return?SQL 中逻辑查询处理中的 GROUP BY 阶段返回什么?
【发布时间】:2013-11-08 12:34:30
【问题描述】:

在 Querying MS SQL Server 2012 (Training Kit) for Exam 70-461 一书中,它谈到了逻辑处理中查询的GROUP BY 阶段:

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

然后作者提到了他使用COUNT(*) > 1HAVING 步骤。我的问题是如果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;

请指教。

【问题讨论】:

  • 您可以发布查询吗?
  • Count(*) 在分组阶段之前计算。
  • @Arvo 与分组阶段同时计算,属于同一操作(Stream/hash聚合)
  • 我认为在分组之后有一个位置。我不知道有什么实际区别。 SQL select 语句设计稍有错误。

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


【解决方案1】:

当作者在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) 有 3 个不同的元组 - (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) - 所以每个行有两个输入行,这就是 COUNT(*) 的含义指的是,不是结果集中的行数。

任何聚合函数(无论是在有还是在选择中)都是在同时作为 GROUP BY 计算的,而不是在它们各自的部分(HAVING、SELECT)。它们是相同的操作,这就是它在用于选择或拥有之前保持组中行数的知识的方式。

Stackoverflow 上的There is very good answer 解释聚合如何在幕后工作以供进一步阅读,所以我不会在这里重复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多