2013-05-08 58 views
3

我有一张有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 

如果类型为具有值1时,然后,在枢转表DCID1应该具有的值,或者如果类型是2 DCID2应具有价值等。同样对应​​也需要放置在IND1,IND2,IND3那样。

如何转发?

回答

5

我的建议是看看使用UNPIVOT和PIVOT函数来得到结果。

的UNPIVOT将用于所述DCI和​​多个列分成多个行转换在单个列中。一旦完成,您可以将数据转回列。

的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和​​名称和它串接到年底type值。这个新的价值将是你申请什么枢轴:

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 | 
+0

我已经转义了,我的表中有ID,Type,DCID,IND,它有超过1亿条记录。而我再次枢轴我得到1000万条记录(pivoted)后内存异常错误。我可否知道哪些是转移这些记录的最佳方式? – man69 2013-05-09 17:14:06

+0

@AnandMuthiah对,这进一步将'DCID'和'IND'转化为同一列。 – Taryn 2013-05-09 17:14:48

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; 

execution plan