几行信息到一行
Several rows with info to a single row
您好,我需要合并 2 个包含客户信息的表。 Table 2 告诉我们是否有关于电子邮件、地址和电话号码的客户信息,但数据是结构化的,因此每个客户有 3 行。有没有办法合并这两个表,以便每个客户只得到一行,但包含所有联系信息?
Table 1:
id customerID ... ...
1 11
2 99
和Table 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
哪个确实能完成这项工作,但如果我以后必须再做一次,有没有更聪明的方法?
谢谢
好吧,如果它有效,为什么要改变它?但如果你必须这样做,也许是这样的:
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
如果您希望将来有新频道,您可以使用它来动态添加频道作为列:
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)
您可以用单个 usong 条件聚合 (=pivot) 替换这三个联接:
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
这可能更有效,请查看说明...
您好,我需要合并 2 个包含客户信息的表。 Table 2 告诉我们是否有关于电子邮件、地址和电话号码的客户信息,但数据是结构化的,因此每个客户有 3 行。有没有办法合并这两个表,以便每个客户只得到一行,但包含所有联系信息?
Table 1:
id customerID ... ...
1 11
2 99
和Table 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
哪个确实能完成这项工作,但如果我以后必须再做一次,有没有更聪明的方法?
谢谢
好吧,如果它有效,为什么要改变它?但如果你必须这样做,也许是这样的:
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
如果您希望将来有新频道,您可以使用它来动态添加频道作为列:
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)
您可以用单个 usong 条件聚合 (=pivot) 替换这三个联接:
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
这可能更有效,请查看说明...