如果列B为空,如何从列A插入数据,如果列A为空,则如何从列B插入数据

时间:2012-04-21 20:15:53

标签: sql sql-server-2008 tsql

我想我已经接近但不确定:

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

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

以下代码不起作用,但它只是展示了我使用过的许多变体:

USE EXAMPLE_DB

GO

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 

谢谢大家!

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

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

INSERT INTO USER_EMAIL(USER_NBR, EMAIL_ADDR)
SELECT USER_NBR, EMAIL_ADDR
FROM EMAIL_DATA
WHERE EMAIL_ADDR IS NOT NULL

答案 2 :(得分:0)

这样做如下:如果EMAIL_ADDR为空,它将查看同一个表并搜索同一用户的其他电子邮件类型的电子邮件。这是你想要的吗?

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