根据单个不同的列选择唯一的行


71

我想选择具有的行distinct email,请参见下面的示例表:

+----+---------+-------------------+-------------+
| id | title   | email             | commentname |
+----+---------+-------------------+-------------+
|  3 | test    | rob@hotmail.com   | rob         |
|  4 | i agree | rob@hotmail.com   | rob         |
|  5 | its ok  | rob@hotmail.com   | rob         |
|  6 | hey     | rob@hotmail.com   | rob         |
|  7 | nice!   | simon@hotmail.com | simon       |
|  8 | yeah    | john@hotmail.com  | john        |
+----+---------+-------------------+-------------+

理想的结果将是:

+----+-------+-------------------+-------------+
| id | title | email             | commentname |
+----+-------+-------------------+-------------+
|  3 | test  | rob@hotmail.com   | rob         |
|  7 | nice! | simon@hotmail.com | simon       |
|  8 | yeah  | john@hotmail.com  | john        |
+----+-------+-------------------+-------------+

我不在乎id返回哪个列值。所需的SQL是什么?

Answers:


97

在TSQL中快速入门

SELECT a.*
FROM emails a
INNER JOIN 
  (SELECT email,
    MIN(id) as id
  FROM emails 
  GROUP BY email 
) AS b
  ON a.email = b.email 
  AND a.id = b.id;

1
哇,真是快家伙!:)笔记本电脑的答案是最短,最简单的,谢谢!
Flo

8
distinct关键字是没有必要在这里。此外,似乎加入id也可以解决问题。
亚当·罗宾逊

我有一个带有主键且两列总计的巨大表,在那种情况下它不起作用
AurA

@downvoter,您不工作是什么意思,也许会是另一个问题?
Turbot

2
太好了,我将最小值更改为最大值,以得到重复项中的最后一行,而不是第一行
Mian Asbat Ahmad

34

我假设你的意思是你不关心哪一行来获得titleidcommentname值(你有“抢”的所有行,但我不知道那其实是东西会被强制执行或不在您的数据模型中)。如果是这样,则可以使用窗口功能返回给定电子邮件地址的第一行:

select
    id,
    title,
    email,
    commentname

from
(
select 
    *, 
    row_number() over (partition by email order by id) as RowNbr 

from YourTable
) source

where RowNbr = 1

2
这是最好的解决方案,因为它可以应用于没有唯一标识列的重复行或具有唯一标识列的重复行。
安东尼·布斯

....是的,这为我解决了这个问题。...以上解决方案仅将表数据分组在一起...即,对于Microsoft SQL 2008 Server /数据..........感谢Adam。 ....
Siwoku Adeola

4

如果您使用的是MySql 5.7或更高版本,则根据这些链接(MySql OfficialSO QA),我们可以为每个记录选择一个记录group by,而无需任何聚合函数。

因此查询可以简化为此。

select * from comments_table group by commentname;

这里试用实际查询


不幸的是,该问题被标记为tsql和sqlserver。
2016年

1
尽管这是对错误问题的正确答案,但我最终还是在这里寻找mysql的解决方案,因此请多多指教
Rick Kukiela,

1
好的解决方案值得更多尊重
王凯

2

由于您不在乎要返回哪个ID,因此我会为每封电子邮件使用MAX ID来简化SQL查询,请尝试一下

;WITH ue(id)
 AS
 (
   SELECT MAX(id)
   FROM table
   GROUP BY email
 )
 SELECT * FROM table t
 INNER JOIN ue ON ue.id = t.id
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.