2014-01-20 67 views
1

我的數據是這樣的:PIVOT多個列

Product Group  Product Level Quatity Sold  Trend 
============================================================== 
Group 1   L1    10    up 
Group 1   L2    20    up 
Group 1   L3    30    down 
Group 2   L1    20    up 
Group 2   L2    40    up 
Group 2   L3    60    down 
Group 2   L4    80    down 

我需要的數據格式爲:

Product Group  L1  L1Trend L2 L2Trend L3 L3Trend L4  L4Trend 
====================================================================================== 
Group 1   10  up   20 up   30 down 
Group 2   20  up   40 up   60 down  80  down 

我能夠使用的東西「產品等級」樞如:

PIVOT (MAX(quatity)  FOR productlevel IN([L1],[L2],[L3],[L4]) AS p 

但在處理這一趨勢時丟失了。

謝謝。

回答

3

你可以通過實現旋轉功能得到想要的結果,但我會第一UNPIVOT的Quantity SoldTrend你多列。 unpivot進程會將它們從多列轉換爲多行數據。

由於您使用的SQL Server 2008+,你可以使用CROSS APPLYVALUES到unpivot的數據:

select [Product Group], 
    col, value 
from yourtable 
cross apply 
(
    values 
    ([Product Level], cast([Quatity Sold] as varchar(10))), 
    ([Product Level]+'trend', [trend]) 
) c (col, value); 

SQL Fiddle with Demo此表格數據轉換成格式:

| PRODUCT GROUP |  COL | VALUE | 
|---------------|---------|-------| 
|  Group 1 |  L1 | 10 | 
|  Group 1 | L1trend | up | 
|  Group 1 |  L2 | 20 | 
|  Group 1 | L2trend | up | 
|  Group 1 |  L3 | 30 | 
|  Group 1 | L3trend | down | 

現在您可以輕鬆應用PIVOT功能:

select [Product Group], 
    L1, L1trend, 
    L2, L2trend, 
    L3, L3trend, 
    L4, L4trend 
from 
(
    select [Product Group], 
    col, value 
    from yourtable 
    cross apply 
    (
    values 
     ([Product Level], cast([Quatity Sold] as varchar(10))), 
     ([Product Level]+'trend', [trend]) 
) c (col, value) 
) d 
pivot 
(
    max(value) 
    for col in (L1, L1trend, L2, L2trend, 
       L3, L3trend, L4, L4trend) 
) piv; 

SQL Fiddle with Demo。這給你最後的結果:

| PRODUCT GROUP | L1 | L1TREND | L2 | L2TREND | L3 | L3TREND |  L4 | L4TREND | 
|---------------|----|---------|----|---------|----|---------|--------|---------| 
|  Group 1 | 10 |  up | 20 |  up | 30 | down | (null) | (null) | 
|  Group 2 | 20 |  up | 40 |  up | 60 | down |  80 | down | 
0

你有可能做到這一點使用相關子查詢:

select productGroup as [Product Group] 
    , (select sum(quantitySold) from myTable where productGroup = a.productGroup and productLevel = 'L1') as L1 
    , (select max(trend) from myTable where productGroup = a.productGroup and productLevel = 'L1') as L1Trend 
    , (select sum(quantitySold) from myTable where productGroup = a.productGroup and productLevel = 'L2') as L2 
    , (select max(trend) from myTable where productGroup = a.productGroup and productLevel = 'L2') as L2Trend 
    -- etc. 
from myTable a 
group by productGroup 
order by productGroup 

這裏是一個example SqlFiddle

在使用PIVOT關鍵字之前,可能會幫助您以此方式查看它。

但是,如果您不知道有多少個productLevel值,則需要動態解決方案。

+0

感謝您的答覆。有沒有辦法只使用PIVOT解決這個問題,而不使用相關的子查詢? – notlkk

0

,如果你喜歡使用支點,你可以試試這個:

select productgroup, 
coalesce(L1up,L1down,'') L1, case when L1up is not null then 'up' when L1down is not null then 'down' else '' end L1trend, 
coalesce(L2up,L2down,'') L2, case when L2up is not null then 'up' when L2down is not null then 'down' else '' end L2trend, 
coalesce(L3up,L3down,'') L3, case when L3up is not null then 'up' when L3down is not null then 'down' else '' end L3trend, 
coalesce(L4up,L4down,'') L4, case when L4up is not null then 'up' when L4down is not null then 'down' else '' end L4trend 
from 
(
select productgroup, [L1up],[L2up],[L3up],[L4up],[L1down],[L2down],[L3down],[L4down] 
from (select productgroup, productlevel+trend pt, quantity from mytable) t 
PIVOT (MAX(quantity) 
FOR pt IN([L1up],[L2up],[L3up],[L4up],[L1down],[L2down],[L3down],[L4down])) as p 
) t