如何在 T-SQL 中使用 group by 和 union

Posted

技术标签:

【中文标题】如何在 T-SQL 中使用 group by 和 union【英文标题】:How to use group by with union in T-SQL 【发布时间】:2010-12-08 22:56:04 【问题描述】:

?我想按联合结果的第一列进行分组,我编写了以下 SQL 但它不起作用。我只是不知道如何引用并集结果的指定列(在本例中为 1)。

SELECT  *
FROM    ( SELECT    a.id ,
                    a.time
          FROM      dbo.a
          UNION
          SELECT    b.id ,
                    b.time
          FROM      dbo.b
        )
GROUP BY 1

【问题讨论】:

【参考方案1】:

您需要为子查询设置别名。因此,您的陈述应该是:

Select Z.id
From    (
        Select id, time
        From dbo.tablea
        Union All
        Select id, time
        From dbo.tableb
        ) As Z
Group By Z.id

【讨论】:

它给出的“时间”在选择列表中无效,因为它不包含在聚合或GROUP BY 中。如果我有许多字段,我必须将它们全部添加到我的 GROUP BY 如果您尝试在外部查询中返回time,那么您正在尝试完成什么问题。如果您想要的只是 id,time 的唯一列表,那么您不需要 Group By,应该将 Union All 更改为 Union。【参考方案2】:

按 1 分组

我从来不知道 GROUP BY 支持使用序数,只有 ORDER BY。无论哪种方式,只有 mysql 支持 GROUP BY 不包括所有没有对其执行聚合函数的列。也不建议使用序数,因为如果它们基于 SELECT 的顺序 - 如果发生变化,您的 ORDER BY(或 GROUP BY,如果支持)也会发生变化。

当您使用UNION 时,无需在内容上运行GROUP BY - UNION 可确保删除重复项; UNION ALL 更快,因为它没有 - 在这种情况下,您将需要 GROUP BY...

您的查询只需:

SELECT a.id,
       a.time
  FROM dbo.TABLE_A a
UNION
SELECT b.id,
       b.time
  FROM dbo.TABLE_B b

【讨论】:

有些用例希望在联合的结果上使用GROUP BY。在给出的示例中,您可以获取每个 ID 的最近时间,无论该时间是在 TABLE_A 还是 TABLE_B 中。您需要一个具有 MAX(time) 的 GROUP BY 来实现这一目标。【参考方案3】:

识别列很容易:

SELECT  *
FROM    ( SELECT    id,
                    time
          FROM      dbo.a
          UNION
          SELECT    id,
                    time
          FROM      dbo.b
        )
GROUP BY id

但它并没有解决这个查询的主要问题:在按第一列分组后如何处理第二列值?由于(特别!)您使用的是UNION 而不是UNION ALL,因此联合中的两个子表之间不会有完全重复的行,但您可能仍然有多个值id 的一个值的时间,并且您没有暗示您想要做什么 - 最小值,最大值,平均值,总和还是什么?!因此,SQL 引擎应该会给出一个错误(尽管一些如 mysql 只是从几个中选择一个随机值,但我相信 sql-server 比这更好)。

所以,比如把第一行改成SELECT id, MAX(time)之类的!

【讨论】:

【参考方案4】:
with UnionTable as  
(
    SELECT a.id, a.time FROM dbo.a
    UNION
    SELECT b.id, b.time FROM dbo.b
) SELECT id FROM UnionTable GROUP BY id

【讨论】:

嗨,欢迎来到 Stack Overflow。如果您在代码中包含解释,那就太好了。在没有任何解释的情况下,很难弄清楚你为什么决定以这种方式解决问题。 嗯,这仍然是一个很好的答案/解决方案,即使没有额外的文本,到目前为止还没有其他人提出。绝对 +1

以上是关于如何在 T-SQL 中使用 group by 和 union的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SELECT 部分中包含 BIT 类型列而不在 T-SQL 中的 GROUP BY 中包含它?

带有 GROUP BY id 的 T-SQL SELECT

T-Sql语法:GROUP BY子句GROUPING SETSCUBEROLLUP

T-SQL:GROUP BY,但保留一个未分组的列(或重新加入它)?

在 group by 中,有没有办法告诉 SQL 特定列不需要聚合函数?

如何在 GROUP BY 和 ORDER BY 中使用多列但只有一列