我有一个包含4列和超过1亿条记录的表格。 表设计:
ID char(12) PK
Type Char(2) PK (Values 1,2,3)
DCID varchar(10) Null
IND Varchar(2) Null (Values Y, N)
这需要像
一样进行转动ID, DCID1, DCID2, DCID3, IND1, IND2, IND3
如果Type的值为1,那么在Pivoted表中,DCID1
应该具有值,或者Type为2 DCID2
应该具有值,依此类推。此外,还需要将IND
替换为IND1
,IND2
,IND3
。
如何转动这个?
答案 0 :(得分:5)
我的建议是看看使用UNPIVOT和PIVOT函数来获得结果。
UNPIVOT将用于将DCI
和IND
多个列转换为单个列中的多个行。完成后,您可以将数据转回到列中。
UNPIVOT代码与此类似:
select id,
col +type as new_col,
value
from
(
select id,
type,
dcid,
cast(ind as varchar(10)) ind
from yt
) d
unpivot
(
value
for col in (DCID, IND)
) unpiv;
见SQL Fiddle with Demo。这给出了一个结果:
| ID | NEW_COL | VALUE |
----------------------------------
| 1 | dcid1 | test |
| 1 | ind1 | Y |
| 2 | dcid2 | est |
| 2 | ind2 | Y |
new_col
包含DCID
和IND
个名称,并且type
值连接到最后。这个新值将是您将PIVOT应用于:
select id, DCID1, DCID2, DCID3, IND1, IND2, IND3
from
(
select id,
col +type as new_col,
value
from
(
select id,
type,
dcid,
cast(ind as varchar(10)) ind
from yt
) d
unpivot
(
value
for col in (DCID, IND)
) unpiv
) src
pivot
(
max(value)
for new_col in (DCID1, DCID2, DCID3, IND1, IND2, IND3)
) piv;
见SQL Fiddle with Demo。结果将是:
| ID | DCID1 | DCID2 | DCID3 | IND1 | IND2 | IND3 |
-------------------------------------------------------------
| 1 | test | | | Y | | |
| 2 | | est | | | Y | |
| 3 | | | blah | | | Y |
| 4 | yes | | | N | | |
| 5 | | hs | | | N | |
| 6 | | | jr | | | N |
答案 1 :(得分:5)
如果源数据如下所示:
+----+------+------+-----+
| ID | TYPE | DCID | IND |
+----+------+------+-----+
| 1 | 1 | test | Y |
| 1 | 2 | est | Y |
| 1 | 3 | blah | Y |
| 2 | 1 | yes | N |
| 2 | 2 | hs | N |
| 2 | 3 | jr | N |
+----+------+------+-----+
所需的输出是:
+-------+-------+-------+------+------+------+
| DCID1 | DCID2 | DCID3 | IND1 | IND2 | IND3 |
+-------+-------+-------+------+------+------+
| test | est | blah | Y | Y | Y |
| yes | hs | jr | N | N | N |
+-------+-------+-------+------+------+------+
一个解决方案是(SQLfiddle):
SELECT
DCID1 = MAX(CASE WHEN type = '1' THEN dcid ELSE NULL END),
DCID2 = MAX(CASE WHEN type = '2' THEN dcid ELSE NULL END),
DCID3 = MAX(CASE WHEN type = '3' THEN dcid ELSE NULL END),
IND1 = MAX(CASE WHEN type = '1' THEN ind ELSE NULL END),
IND2 = MAX(CASE WHEN type = '2' THEN ind ELSE NULL END),
IND3 = MAX(CASE WHEN type = '3' THEN ind ELSE NULL END)
FROM yt
GROUP BY id
ORDER BY id;