Sql server SQL Select不同于只返回一行的多个字段

Sql server SQL Select不同于只返回一行的多个字段,sql-server,unique,distinct-values,Sql Server,Unique,Distinct Values,我在SQL Server中有一个包含以下列的表: MEMBERID, MEMBEREMAIL, FATHEREMAIL, MOTHEREMAIL, MEMBERNAME MEMBERID是主键。这三个电子邮件列不是唯一的,因此同一电子邮件可能在同一行和多行中出现多次 我正在尝试提取一个唯一的电子邮件列表,并且对于每封电子邮件,还将获得一个memberid和membername(从哪个记录中提取并不重要) 例如,如果我有三行: 1 x@x.com y@y.com y@y.com

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

MEMBERID, MEMBEREMAIL, FATHEREMAIL, MOTHEREMAIL, MEMBERNAME
MEMBERID
是主键。这三个电子邮件列不是唯一的,因此同一电子邮件可能在同一行和多行中出现多次

我正在尝试提取一个唯一的电子邮件列表,并且对于每封电子邮件,还将获得一个
memberid
membername
(从哪个记录中提取并不重要)

例如,如果我有三行:

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
)并为其中的每一个添加一个
成员ID
。它不知道哪个
成员ID
(例如
x@X.com
只要
x@x.com
在结果中仅出现一次


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

您可以使用子查询来规范化所有电子邮件。然后您可以使用
行号
筛选出每封电子邮件的一个
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
请在以下位置尝试这两个版本:


此代码将为您提供一组正确的不同电子邮件: 然后,您可以从查询成员中创建一个游标,然后获得每个成员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行并多次重复。John 1x@x.com约翰1y@y.com马克2x@x.com马克2y@y.com马克2z@z.com苏珊3x@x.com苏珊3y@y.com苏珊3z@z.cm