【问题标题】:select unique rows based on single distinct column基于单个不同列选择唯一行
【发布时间】:2012-01-06 14:55:42
【问题描述】:

我想选择具有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 是什么?

【问题讨论】:

    标签: sql-server tsql


    【解决方案1】:

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

    所以查询可以简化成这样。

    select * from comments_table group by commentname;

    在行动中试用查询here

    【讨论】:

    • 不幸的是,这个问题被标记为 tsql 和 sqlserver。
    • 尽管这是对错误问题的正确答案,但我最终还是在这里为 mysql 寻找这个解决方案,所以带上我的 updoot
    • 好的解决方案值得更多尊重
    【解决方案2】:

    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;
    

    【讨论】:

    • 哇,伙计们太快了!:) 笔记本电脑的答案是最短和最简单的,谢谢!
    • 这里不需要distinct 关键字。此外,似乎只加入 id 也可以解决问题。
    • 我有一个巨大的表,主键是两列的聚合,在这种情况下它不起作用
    • @downvoter ,不工作是什么意思,也许是另一个问题?
    • 太好了,我将最小值更改为最大值以获取副本中的最后一行而不是第一行
    【解决方案3】:

    由于您不在乎返回哪个 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
    

    【讨论】:

      【解决方案4】:

      我假设您的意思是您不关心用于获取 titleidcommentname 值的行(您对所有行都有“rob”,但我不关心'不知道这是否真的会在您的数据模型中强制执行)。如果是这样,那么您可以使用窗口函数返回给定电子邮件地址的第一行:

      select
          id,
          title,
          email,
          commentname
      
      from
      (
      select 
          *, 
          row_number() over (partition by email order by id) as RowNbr 
      
      from YourTable
      ) source
      
      where RowNbr = 1
      

      【讨论】:

      • 这是最好的解决方案,因为它可以应用于没有唯一标识列的重复行,或者具有唯一标识列的行。
      • ....是的,这为我解决了这个问题....上面的解决方案只将表数据分组在一起......即用于 Microsoft SQL 2008 Server/data...... ....谢谢亚当......
      • 这是一个非常好的解决方案,适用于较小的表。有没有办法做到这一点,而不必在 SELECT 语句中列出每一列?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-16
      • 1970-01-01
      相关资源
      最近更新 更多