使用 Group By 时如何区分记录?

Posted

技术标签:

【中文标题】使用 Group By 时如何区分记录?【英文标题】:How to distinct the record when using Group By? 【发布时间】:2011-05-05 14:43:15 【问题描述】:

你好, 我有一张表(如下所示),它有 4 条记录。请注意,ColumnA 和 ColumnB 具有相同的值,而 ColumnC 和 columnD 将具有不同的值。

ColumnA ColumnB ColumnC ColumnD
------- ------- ------- -------
xx      yy      AAA     333
xx      yy      BBB     555
xx      yy      AAA     333
xx      yy      BBB     555

我试图使用 Group By 查询选择整条记录,如下所示:

SELECT ColumnC from TableA GROUP BY ColumnC;

这个查询只显示了 ColumnC,但我的期望是选择整个记录,而不仅仅是 ColumnC。

更新:我的预期输出是:

ColumnA ColumnB ColumnC ColumnD
------- ------- ------- -------
xx      yy      AAA     333
xx      yy      BBB     555

请问我该怎么做?

谢谢@!

【问题讨论】:

如果您只想按 ColumnC 进行分组,并且想要“整个记录”,那么您希望其余列的值是多少? 对于什么数据库?因为 ANSI 规范和供应商实现之间的行为不同 - 请参阅我对 Egor4eg 答案的评论。 您使用的是哪个 DBMS?答案可能有助于完善答案。 @Lamak:我在问题中添加了我的预期输出。 【参考方案1】:

您可以将所有列放在 SELECT 和 GROUP BY 子句中:

SELECT 
    ColumnA, ColumnB, ColumnC, ColumnD 
FROM 
    TableA 
GROUP BY
    ColumnA, ColumnB, ColumnC, ColumnD

这基本上相当于

SELECT DISTINCT
    *
FROM
    TableA

但更明确。正如 OMG Ponies 所指出的,DBMS 之间的语法可能有所不同。在某些情况下,您可能可以简单地这样做:

SELECT * FROM TableA GROUP BY ColumnC

【讨论】:

我是在Oracle中做的,之前也试过,但是输出和原表完全一样。我确实尝试过 SELECT distinct(columnC), distinct(columnD) from tableA;但它也不能正常工作。这个查询会给我一个错误:ORA-00936: missing expression. @huahsin68: DISTINCT 适用于,而不适用于列。您不能通过简单地将 DISTINCT 放在您想要的位置来强制某些列是不同的,而另一些则不是。方法如下:SELECT DISTINCT columnA, columnB, columnC, columnD FROM tableA.【参考方案2】:

在甲骨文中:

SELECT  *
FROM    (
        SELECT  t.*,
                ROW_NUMBER() OVER (PARTITION BY columnC ORDER BY columnA) AS rn
        FROM    mytable
        )
WHERE   rn = 1

更改ORDER BY 子句以控制将返回哪些包含重复项的记录(现在columnA 的值最小)。

【讨论】:

根据您的查询,我必须按 columnD 排序,这样才能得到预期的输出。如果我按其他列排序,则 rn 值将与 3、7、8、9 不同。我可以知道为什么会这样吗?顺便说一句,“分区依据”对我来说是一个新术语。 @huahsin68:我的查询甚至没有提到columnD【参考方案3】:

如果您使用的是 MS SQL,以下将为您提供所需的内容:SELECT ColumnC,* from TableA GROUP BY ColumnC;

在 Oracle 中,我相信 select ColumnC, TableA.* from TableA GROUP BY COLUMNC; 会帮助您实现目标。

【讨论】:

我在 Oracle 中做,这不起作用。它给了我一个错误 ORA-00936: missing expression。 我重新标记了问题以包括 oracle。我的答案适用于 MS SQL。【参考方案4】:
SELECT * from TableA GROUP BY ColumnC;

【讨论】:

这不起作用。您不能在 SELECT 中包含列而不将它们包含在聚合函数或 GROUP BY 子句中。 @Cory Larson:实际上,这是 ANSI(92?)SQL 规范所指定的——但很少有数据库实现它。 mysql 和 SQLite 是我所知道的唯一支持可选的 GROUP BY 列。 @CoryLarson:它(遗憾的是)默认在 MySQL 中工作,它从任意行中选择值;您可以使用ONLY_FULL_GROUP_BY sql_mode 将其关闭。此外,最新的 SQL 标准显然使它变得更加复杂,如果数据库知道某个列在“功能上”依赖于 group-by 列,则它本身不需要在 group by 或聚合中。 @OMG Ponies:我的立场是正确的......这通常*不起作用。 大家好,我是在 Oracle 中做的,这个查询给我一个错误:ORA-00979: not a GROUP BY expression【参考方案5】:

您可能想要选择所有列,然后需要先分组,C 列是第一个: SELECT * FROM TableA GROUP BY ColumnC, ColumnA, ColumnB, ColumnD

【讨论】:

以上是关于使用 Group By 时如何区分记录?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL Query - 使用 group-by 时获取丢失的记录

如何在linq C#中使用group by并获取记录列表[重复]

如何使用 group by [重复] 使用 mySQL 删除数据库中的记录

MYSQL使用group by,如何查询出总记录数

sql如何取group by 分组的多条记录只取最上面的一条!

如何连接具有不同 GROUP BY 级别的两个查询,使一些记录为空