2014-01-29 32 views
0

我有一個數據集視圖,需要進行旋轉,AMC1,AMC2和AMC3的列標題將成爲LOB下的行。這裏是原單的例子:如何PIVOT列標題 - SQL數據

Qtr Year BU BU_Description P2A_Line  AMC1 AMC2 AMC3 
Q3 2013 B52100 52100 - UFC  L1_1   203 17  7 
Q3 2013 B52100 52100 - UFC  L1_2   -  -  - 
Q3 2013 B52100 52100 - UFC  L1_3   123 113 - 

這裏是最終結果的例子:

Qtr Year BU BU_Description LOB  L1_1 L1_2 PL1_3 
    Q3 2013 B52100 52100 - UFC AMC1 203  -  123 
    Q3 2013 B52100 52100 - UFC AMC2 17  -  113 
    Q3 2013 B52100 52100 - UFC AMC3 7  -  - 

有沒有人有一個簡單的和相對簡單的方式做到這一點?那裏的例子有太多的變量來推導答案。任何幫助將不勝感激?

+0

哪些DBMS是你在用嗎? Postgres的?甲骨文? –

+0

@ a_horse_with_no_name SQL Server Management Studio –

+0

這不是一個DBMS,這是一個客戶端工具 - 但是因爲它只支持Microsoft SQL Server,所以我猜你正在使用它。 –

回答

2

通過使用帶有CASE表達式的集合函數(使用PIVOT函數),您可以通過幾種不同的方式獲得結果 - 但在實現這些方法之前,您首先需要查看未清理多列數據的方法 - AMC1AMC2AMC3

未轉換的過程會將多列轉換爲行。您可以使用逆透視功能,也可以使用CROSS APPLY將數據轉換:

select qtr, year, bu, bu_description, p2a_line, 
    lob, value 
from yourtable 
cross apply 
(
    select 'amc1', amc1 union all 
    select 'amc2', amc2 union all 
    select 'amc3', amc3 
) c (lob, value); 

SQL Fiddle with Demo。一旦數據是這種格式,那麼你可以將你的P2A_Line值轉換成列。

使用帶有CASE表達式集合函數查詢將是:

select qtr, year, bu, bu_description, 
    lob, 
    max(case when p2a_line = 'L1_1' then value end) L1_1, 
    max(case when p2a_line = 'L1_2' then value end) L1_2, 
    max(case when p2a_line = 'L1_3' then value end) L1_3 
from 
(
    select qtr, year, bu, bu_description, p2a_line, 
    lob, value 
    from yourtable 
    cross apply 
    (
    select 'amc1', amc1 union all 
    select 'amc2', amc2 union all 
    select 'amc3', amc3 
) c (lob, value) 
) d 
group by qtr, year, bu, bu_description, lob; 

參見SQL Fiddle with Demo

在SQL Server 2005 +,你可以使用旋轉功能:

select qtr, year, bu, bu_description, 
    lob, L1_1, L1_2, L1_3 
from 
(
    select qtr, year, bu, bu_description, p2a_line, 
    lob, value 
    from yourtable 
    cross apply 
    (
    select 'amc1', amc1 union all 
    select 'amc2', amc2 union all 
    select 'amc3', amc3 
) c (lob, value) 
) d 
pivot 
(
    max(value) 
    for p2a_line in (L1_1, L1_2, L1_3) 
) piv; 

SQL Fiddle with Demo

最後,如果你有數目不詳的p2a_line值,那麼你可以使用動態SQL:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT ',' + QUOTENAME(P2A_Line) 
        from yourtable 
        group by P2A_Line 
        order by P2A_Line 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = N'SELECT qtr, year, bu, bu_description, lob,' + @cols + N' 
      from 
      (
       select qtr, year, bu, bu_description, p2a_line, 
       lob, value 
       from yourtable 
       cross apply 
       (
       select ''amc1'', amc1 union all 
       select ''amc2'', amc2 union all 
       select ''amc3'', amc3 
      ) c (lob, value) 
      ) x 
      pivot 
      (
       max(value) 
       for p2a_line in (' + @cols + N') 
      ) p ' 

execute sp_executesql @query; 

SQL Fiddle with Demo

所有版本給出的結果是:

| QTR | YEAR |  BU | BU_DESCRIPTION | LOB | L1_1 | L1_2 | L1_3 | 
|-----|------|--------|----------------|------|------|--------|--------| 
| Q3 | 2013 | B52100 | 52100 - UFC | amc1 | 203 | (null) | 123 | 
| Q3 | 2013 | B52100 | 52100 - UFC | amc2 | 17 | (null) | 113 | 
| Q3 | 2013 | B52100 | 52100 - UFC | amc3 | 7 | (null) | (null) | 
+0

工作完美,非常感謝! –