2013-05-08 127 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