2016-02-29 80 views
1

您好,我需要合并2个表格与关于客户的信息。表2告诉我们,如果我们有关于电子邮件,地址和电话号码的客户信息,但是数据的结构使每个客户有3行。有没有合并这两个表的方法,以便我只为每个客户获得一行,但包含所有联系信息?几行信息到单行

表1:

id customerID ... ... 

1 11 

2 99 

和表2:

id customerID Channel Y_N 

1 11   Email Y 

2 11   Address Y 

3 11   Phone N 

4 99   Email N 

5 99   Address Y 

6 99   Phone N 

我的代码是这样的

TABLE 1 
left join(
    select customerID, 
    case when Y_N='Y' and Channel='Email' then 1 else 0 end as Email 
    FROM table2 
    where Channel='Email')a 
    on table1.customerID=a.customerID 
Left join(
    select customerID, 
    case when Y_N='Y' and Channel='Address' then 1 else 0 end as Address 
    FROM table2 
    where Channel='Address') b 
    on table1.customerID=b.customerID 
Left join(
    select customerID, 
    case when Y_N='Y' and Channel='Phone' then 1 else 0 end as Phone 
    FROM table2 
    where Channel='SMS') c 
    on table1.customerID=c.customerID 

实际上做的工作,但如果我要再做一次在未来有没有更聪明的方法?

谢谢

回答

1

可以替换这三个与单个usong条件聚合加入(=枢轴):

TABLE1 
left join(
    select customerID, 
     max(case when Y_N='Y' and Channel='Email' then 1 else 0 end) as Email 
     max(case when Y_N='Y' and Channel='Address' then 1 else 0 end) as Address 
     max(case when Y_N='Y' and Channel='Phone' then 1 else 0 end) as Phone 
    FROM table2 
    GROUP BY 1) a 
    on table1.customerID=a.customerID 

这可能是更有效,检查解释...

0

好吧,如果它的工作原理,为什么要改变呢?但是,如果你必须这样做,也许是这样的:

SELECT 
    c.*, 
    IF(e.Y_N='Y',1,0) AS Email, 
    IF(a.Y_N='Y',1,0) AS Address, 
    IF(p.Y_N='Y',1,0) AS Phone 
FROM table1 AS c 
    LEFT JOIN table2 AS e ON(c.customerID=e.customerID AND Channel='Email') 
    LEFT JOIN table2 AS a ON(c.customerID=a.customerID AND Channel='Address') 
    LEFT JOIN table2 AS p ON(c.customerID=p.customerID AND Channel='Phone') 

而且,我真的不能看到一个很好的理由,表2中每个客户三行。如果可能的话,你会更好,将其更改为

customerID|Email|Address|Phone 
    11 | 1 | 1 | 0 
    99 | 0 | 1 | 0 

,这样你可以做

SELECT * FROM table1 AS a LEFT JOIN table2 AS b ON a.customerID=b.customerID 
+0

我不负责创建的数据库,我也宁愿把它构造为你展示它:)谢谢 – IDDQD

0

如果您在未来的期待新的渠道,你可以用它来动态地添加信道作为列:

DECLARE @SearchList  varchar(MAX) 
DECLARE @sql   varchar(MAX) 

select @SearchList = COALESCE(@SearchList, '') + ', [' + cast(Channel as VARCHAR(100)) + ']' 
from (select distinct channel from #table2) a 

set @sql = 'select CustomerID, ' + RIGHT(@SearchList, LEN(@SearchList)-1) +' 
from 
(select CustomerID, Channel, Y_N 
    from #table2) as t 
pivot 
(
    max(Y_N) 
    for Channel in (' + RIGHT(@SearchList, LEN(@SearchList)-1) + ') 
) as pvt' 

exec(@sql)