2012-09-24 37 views
1

我有一個表,由於某種原因已經硬編碼像這樣值的行:移調列使用UNPIVOT

Row ID QtyC1 QtyC2 QtyC3 QtyC4 QtyN1 QtyN2 QtyN3 QtyN4 
100  10  5  8  9  11  12  5  6 
101  9  11  12  5  6  10  4  9 

表有35列和周圍12K記錄(意爲各地500K值)和被添加到並不斷修正。

我想在一個視圖轉成這樣:

Row ID Year Period Val 
100  C  1  10 
100  C  2  5 
100  C  3  8 
100  C  4  9 
100  N  1  11 
100  N  2  12 
100  N  3  5 
100  N  4  6 

到目前爲止,我已經成功地出來使用此查詢拆分成單值:

SELECT Row ID, YP, Val 

FROM (SELECT Row ID 
    , QtyC1 AS C1 
    , QtyC2 AS C2 
    , QtyC3 AS C3 
    , QtyC4 AS C4 
    , QtyN1 AS N1 
    , QtyN2 AS N2 
    , QtyN3 AS N3 
    , QtyN4 AS N4 

FROM MyTable 
) SUB 
UNPIVOT (Val FOR YP IN (C1,C2,C3,C4,N1,N2,N3,N4)) AS PVT 

這讓我一個單一識別值(例如C1),但我怎樣才能分割它,所以我有一個數字期間和一年的單個字符(1C)?

我可以看到它可能只是將字符串分成兩部分,但如果可能的話我希望有一個更清潔的方法。

+0

是你要動態地做到這一點?或者你要硬編碼每一列? – Taryn

回答

1

爲什麼這看起來不潔淨?

SELECT Row ID, left(YP, 1) as year, cast(right(yp, 1) as int) as period, Val 
FROM (SELECT Row ID 
    , QtyC1 AS C1 
    , QtyC2 AS C2 
    , QtyC3 AS C3 
    , QtyC4 AS C4 
    , QtyN1 AS N1 
    , QtyN2 AS N2 
    , QtyN3 AS N3 
    , QtyN4 AS N4 
FROM MyTable 
) SUB 
UNPIVOT (Val FOR YP IN (C1,C2,C3,C4,N1,N2,N3,N4)) AS PVT 
+0

這比我想要的要簡單得多,我可能會繼續這樣做! – bendataclear

2

您可以輕鬆地使用拆分LEFT()RIGHT()SUBSTRING(),等我的建議是,你是如何處理你的UNPIVOTYP字符串。看起來你有很多列到UNPIVOT,所以我的建議可能是實現動態SQL來執行此查詢。你會做這種方式:

declare @colsUnpivot varchar(max), 
    @query AS NVARCHAR(MAX), 
    @cols varchar(max) 

select @colsUnpivot = stuff((select ',' 
          +quotename(replace(C.name, 'Qty', '')) 
     from sys.columns as C 
     where C.object_id = object_id('yourtable') and 
       C.name like 'Qty%' 
     for xml path('')), 1, 1, '') 

select @cols = stuff((select ',' 
         +quotename(C.name) + ' as ' + replace(C.name, 'Qty', '') 
     from sys.columns as C 
     where C.object_id = object_id('yourtable') and 
       C.name like 'Qty%' 
     for xml path('')), 1, 1, '') 

set @query 
    = 'select rowid, 
      left(YP, 1) YP, 
      cast(right(YP, len(YP) - 1) as int) period, 
      Val 
    from 
    (
     select rowid, ' + @cols + ' 
     from yourtable 
    ) x1 
    unpivot 
    (
     val for YP IN (' + @colsUnpivot + ') 
    ) u' 

exec(@query) 

看到SQL Fiddle with Demo

+0

這看起來很有用,但我寧願儘可能避免動態sql。 – bendataclear

+0

@bendataclear沒問題,我只是想,我會告訴你一個動態版本,因爲你說你有35列。 – Taryn