【问题标题】:SQL Select distinct from multiple fields returning only one rowSQL Select 与仅返回一行的多个字段不同
【发布时间】:2012-07-03 09:22:39
【问题描述】:

我在 SQL Server 中有一个包含以下列的表:

MEMBERID, MEMBEREMAIL, FATHEREMAIL, MOTHEREMAIL, MEMBERNAME

MEMBERID 是PK。这三个电子邮件列不是唯一的,因此同一电子邮件可能会在同一行和多行中出现多次。

我正在尝试提取一个唯一的电子邮件列表,并且对于每封电子邮件还获得一个 memberidmembername(从哪个记录中获取无关紧要)。

例如,如果我有三行:

1   x@x.com   y@y.com   y@y.com   Mark
2   z@z.com   y@y.com   x@x.com   John
3   x@x.com   y@y.com   z@z.com   Susan

我想获取这三封电子邮件 (x@x.com, y@y.com, z@z.com) 以及它们出现的每封电子邮件的 MEMBERID。它不是 MEMBERID(例如对于 x@X.com,我不在乎我是否得到值 1 和 Mark 或 2 和 John 或 3 和 Susan,只要 x@x.com 在结果中只出现一次。

如果我在尝试返回电子邮件和 memberid 和 membername 时使用 DISTINCT,我当然会得到所有行。

【问题讨论】:

    标签: sql-server unique distinct-values


    【解决方案1】:

    您可以使用子查询来规范所有电子邮件。然后您可以使用row_number 过滤出每封电子邮件一个memberid, membername

    select  *
    from    (
            select  row_number() over (partition by email order by memberid) as rn
            ,       *
            from    (
                    select  MEMBERID
                    ,       MEMBERNAME
                    ,       MEMBEREMAIL as email
                    from    YourTable
                    union all
                    select  MEMBERID
                    ,       MEMBERNAME
                    ,       FATHEREMAIL
                    from    YourTable
                    union all
                    select  MEMBERID
                    ,       MEMBERNAME
                    ,       MOTHEREMAIL
                    from    YourTable
                    ) as emails
            ) num_emails
    where   rn = 1
    

    您还可以使用 UNPIVOT 子句规范化电子邮件,如下所示:

    select  *
    from    (
            select  row_number() over (partition by email order by memberid) as rn
            ,       *
            from    (
                    select  MEMBERID
                    ,       MEMBERNAME
                    ,       email
                    from    YourTable
                    unpivot (
                                    email
                            for     emailOwner
                            in      (
                                    MEMBEREMAIL,
                                    FATHEREMAIL,
                                    MOTHEREMAIL
                                    )
                            ) as u
                    ) as emails
            ) num_emails
    where   rn = 1
    

    SQL Fiddle 尝试这两个版本:

    【讨论】:

      【解决方案2】:

      此代码将为您提供正确的不同电子邮件组: 然后您可以从查询成员中创建一个游标,然后使用this concept 获取每个成员ID 的邮件的逗号分隔列表我会为此创建一个输出表,如果您需要它以供将来使用并制作一个存储过程,这将更容易为此创建自定义表

      select mem.*, mails.MEMBEREMAIL
      from (
          select MEMBERID,max(MEMBERNAME) as MEMBERNAME
          from table
          group by MEMBERID
      )  as mem 
      inner join 
      (
          select distinct MEMBERID, MEMBEREMAIL
          from (
              select MEMBERID, MEMBEREMAIL
              from table
              union
              select MEMBERID, FATHEREMAIL
              from table
              union
              select MEMBERID, MOTHEREMAIL
              from table
          ) as mail
      ) as mails on mem.MEMBERID = mails.MEMBERID
      

      【讨论】:

      • 此代码不会生成不同的电子邮件 - 在示例数据上运行它会生成 8 行多次重复。约翰 1 x@x.com 约翰 1 y@y.com 马克 2 x@x.com 马克 2 y@y.com 马克 2 z@z.com 苏珊 3 x@x.com 苏珊 3 y@y.com 苏珊3 z@z.cm
      猜你喜欢
      • 2021-07-21
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      • 2016-06-11
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多