3

我想我正在接近但不确定:

我有一个包含电子邮件地址、个人和工作的示例表。我正在尝试创建一个包含单个地址的新表。

然后插入一个电子邮件地址,例如:如果用户有工作电子邮件但没有个人电子邮件,则插入工作电子邮件,如果没有工作电子邮件,则插入个人电子邮件。

以下代码不起作用,但它只是为了显示我使用的许多变体中的一些:

使用示例数据库

CREATE TABLE USER_EMAIL(
 USER_NBR CHAR(1) NOT NULL
,EMAIL VARCHAR(30)NULL
)

GO

INSERT INTO USER_EMAIL(
 USER_NBR
,EMAIL
)

SELECT USER_NBR
,CASE WHEN EMAIL_ADDR IS NULL AND EMAIL_TYPE = 'Personal' THEN EMAIL_TYPE = 'Work' END EMAIL
,CASE WHEN EMAIL_ADDR IS NULL AND EMAIL_TYPE = 'Work'     THEN EMAIL_TYPE =  'Personal' END EMAIL
FROM EMAIL_DATA

这是 EMAIL_DATA 的表:

USER_NBR   EMAIL_TYPE       EMAIL_ADDR
1          Personal 
2          Personal     user2personal@demo.com
3          Personal         user3personal@demo.com
4          Personal 
5          Personal         user5personal@demo.com
1          Work         user1work@demo.com
2          Work         user2work@demo.com
3          Work 
4          Work         user4work@demo.com
5          Work 

谢谢大家!

4

3 回答 3

2

这是一个使用示例row_number

insert  user_email
        (user_nbr, email)
select  user_nbr
,       mail.email_addr
from    (
        select  user_nbr
        ,       email_addr
        ,       row_number() over (partition by user_nbr
                  order by
                  case 
                  when email_type = 'personal' then 1
                  when email_type = 'work' then 2
                  end) as rn
        from    email_data
        ) usr
where   usr.rn = 1

由于只有两种电子邮件类型,因此您也可以使用left join两次:

insert  user_email
        (user_nbr, email)
select  user_nbr
,       coalesce(pers.email_addr, work.email_addr)
from    (
        select  distinct user_nbr
        from    email_data
        ) usr
left join 
        email_data as pers 
on      pers.user_nbr = usr.user_nbr
        and work.email_type = 'personal'
left join 
        email_data as work
on      work.user_nbr = usr.user_nbr
        and work.email_type = 'work'

另一种使用以下方法查找首选电子邮件地址的方法cross apply

insert  user_email
        (user_nbr, email)
select  user_nbr
,       mail.email_addr
from    (
        select  distinct user_nbr
        from    email_data
        ) usr
cross apply
        (
        select  top 1 *
        from    email_data mail
        where   mail.user_nbr = usr.user_nbr
                and mail.email_addr is not null
        order by
                case 
                when email_type = 'personal' then 1
                when email_type = 'work' then 2
                end
        ) mail
于 2012-04-21T20:25:54.720 回答
2

根据您的需求说明,每个用户在源中只有一种或另一种类型,听起来您可以简单地这样做:

INSERT INTO USER_EMAIL(USER_NBR, EMAIL_ADDR)
SELECT USER_NBR, EMAIL_ADDR
FROM EMAIL_DATA
WHERE EMAIL_ADDR IS NOT NULL
于 2012-04-21T21:12:33.903 回答
0

这会执行以下操作:如果EMAIL_ADDR为 null,它将查看同一个表并为同一用户搜索其他电子邮件类型的电子邮件。是你想要的吗?

INSERT INTO USER_EMAIL(
 USER_NBR
,EMAIL 
)
SELECT e.USER_NBR
     , EMAIL = COALESCE(e.EMAIL_ADDR
                    , (CASE e.EMAIL_TYPE
                        WHEN 'Work' THEN (SELECT TOP 1 EMAIL_ADDR  
                                      FROM EMAIL_DATA e1
                                      WHERE e1.USER_NBR=e.USER_NBR
                                      AND EMAIL_TYPE='Personal')
                        WHEN 'Personal' THEN (SELECT TOP 1 EMAIL_ADDR 
                                      FROM EMAIL_DATA e1
                                      WHERE e1.USER_NBR=e.USER_NBR
                                      AND EMAIL_TYPE='Work')
                    END))
FROM EMAIL_DATA e

结果与您的样本数据:

USER_NBR    EMAIL
1           user1work@demo.com
2           user2personal@demo.com
3           user3personal@demo.com
4           user4work@demo.com
5           user5personal@demo.com
1           user1work@demo.com
2           user2work@demo.com
3           user3personal@demo.com
4           user4work@demo.com
5           user5personal@demo.com
于 2012-04-21T20:33:09.973 回答