T-SQL从一个表变化的数据,并插入到另一个表

问题描述:

我的基表是这样的:T-SQL从一个表变化的数据,并插入到另一个表

ColumnA|ColumnB 
--------------- 
    A | C1 
    A | C2 
    A | C3 
    B | C1 
    B | C3 
    C | C4 

我想从基础表中读取记录,并将其写入到见下表:

ColumnA | C1 | C2 | C3 | C4 
---------------------------- 
    A | Y | Y | Y | N 
    B | Y | N | Y | N 
    C | N | N | N | Y 

我不想使用游标,但我不知道这是否可能。

感谢

+0

就像一个数据透视表,对吗? – MJB 2010-07-16 15:17:05

+0

是的,我认为但我不知道如何在这里使用 – oshin 2010-07-16 15:18:12

+0

应C-> C4是Y? 你想建立一个真值表还是只显示输出? – 2010-07-16 15:22:49

一个(通常快速)的方法是group by

insert NewTable (ColumnA, C1, C2, C3, C4) 
select ColumnA 
,  IsNull(max(case when ColumnB = 'C1' then 'Y' end), 'N') 
,  IsNull(max(case when ColumnB = 'C2' then 'Y' end), 'N') 
,  IsNull(max(case when ColumnB = 'C3' then 'Y' end), 'N') 
,  IsNull(max(case when ColumnB = 'C4' then 'Y' end), 'N') 
from OldTable 
group by 
     ColumnA 

另一种方式是子查询,如:

insert NewTable (ColumnA, C1, C2, C3, C4) 
select src.ColumnA 
,  case when exists (select * from OldTable ot 
          where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C1') 
        then 'Y' else 'N' end 
,  case when exists (select * from OldTable ot 
          where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C2') 
        then 'Y' else 'N' end 
,  case when exists (select * from OldTable ot 
          where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C3') 
        then 'Y' else 'N' end 
,  case when exists (select * from OldTable ot 
          where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C4') 
        then 'Y' else 'N' end 
from (
     select distinct ColumnA 
     from OldTable 
     ) src 

或者,改编自克里斯潜水员的回答,用pivot

select ColumnA 
,  case when C1 > 0 then 'Y' else 'N' end C1 
,  case when C2 > 0 then 'Y' else 'N' end C2 
,  case when C3 > 0 then 'Y' else 'N' end C3 
,  case when C4 > 0 then 'Y' else 'N' end C4 
from OldTable src 
pivot (
     count(ColumnB) 
     for ColumnB IN ([C1], [C2], [C3], [C4]) 
     ) pvt 
+0

+1。如果在设计时知道枢轴的列数,并且足够小以便通过复制/粘贴这些子查询来管理,则这更容易。 – 2010-07-16 15:23:40

+0

在为什么你在使用MAX? – oshin 2010-07-16 15:29:52

+0

@oshin:您必须为数据库指定一个聚合多行数值的方法。 max()中的表达式返回'Y'表示匹配,'null'表示不匹配。如果找到匹配的行,那么'max()'是'Y',否则是'null'。 – Andomar 2010-07-16 15:32:39

假设你可以选择你喜欢的信息,那么你可以编写插件作为选择的结果。

+0

你是否在我的朋友那里读过这个问题? – oshin 2010-07-16 15:16:01

看看PIVOT命令。从那里,你可以做一个INSERT INTO ... SELECT ...

SELECT ColumnA, [C1], [C2], [C3], [C4] 
FROM (SELECT * FROM table) t 
PIVOT 
(
Count(ColumnB) 
FOR ColumnB IN ([C1], [C2], [C3], [C4]) 
) As Pvt 
+0

因为我只需要Y或N,我如何在这里使用case语句? 我试图计数(columnB)= 0,然后'N'ELSE'Y'END但我得到错误: 关键字'case'附近的语法不正确。 – oshin 2010-07-16 15:47:53

+0

@oshin:在要求苛刻的()时,枢轴是不灵活的。在我的答案中加入了一个数据透视表,但如果您愿意,请接受Chris Diver的答案:) – Andomar 2010-07-16 15:52:15

+0

您必须在select语句中的每个'[Cx]'处添加一个案例。 – 2010-07-16 15:58:23