SQL Server:当存在多行时,基于字段仅选择一行

时间:2014-07-04 14:21:32

标签: sql sql-server

我有一个包含3列的表格:NameSurnameEmail。这些列中的数据不是唯一的。

我需要获得符合以下条件的结果:

  • 选择所有三列
  • 电子邮件记录应该是唯一的
  • 每封电子邮件只应有一条记录

这意味着SELECT DISTINCT不适用,因为它可以检索多个电子邮件记录。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您没有指定您的DBMS,但大多数系统都支持"窗口聚合函数":

with cte as
 ( select Email, Name, Surname,
      row_number() over (partition by Email order by Name) as rn
   from tab
 )
select Email, Name, Surname
from tab
where rn = 1

这会为每封电子邮件分配一个排名,并仅返回第一个。

答案 1 :(得分:0)

如果要显示与每封电子邮件关联的所有唯一名称,每封电子邮件一行,您可以使用字符串聚合。

如果使用MySQL(您没有指定数据库):

select group_concat(distinct name order by name separator ', ') as names,
       group_concat(distinct surename order by name separator ', ') as surenames,
       email
  from tbl
 group by email

如果使用PostgreSQL,则string_agg是等效的。如果使用Oracle,则为listagg。

如果您只是随意想要与电子邮件关联的任何名称,并且您不关心哪个名称,只要它只有一个,您就可以使用之前的答案。

但是,如果您的数据库不支持with子句或窗口函数(即MySQL),您可以使用以下内容随意显示每封电子邮件的名称和姓氏:

select x.*, y.surname
  from (select email, max(name) as name from tbl group by email) x
  join tbl y
    on x.name = y.name
   and x.email = y.email

这将显示给定名称的正确姓氏,因为它首先选择max(名称),然后获取该名称和电子邮件的姓氏。