2013-10-31 150 views
1

我正在嘗試使用數據透視表來獲取diff格式的信息。數據透視表丟失列

這裏是我的表:

CREATE TABLE yourtable 
([case] int, [category] varchar(4)) 
    ; 

    INSERT INTO yourtable 
([case], [category]) 
    VALUES 
(1, 'xx'), 
(1, 'xyx'), 
(1, 'abc'), 
(2, 'ghj'), 
(2, 'asdf'), 
(3, 'dfgh') 
    ; 

這裏是bluefeet我轉動命令禮遇:

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

    select @cols = STUFF((SELECT distinct ',' + QUOTENAME('cat'+cast(seq as  
    varchar(10))) 
       from 
       (
        select row_number() over(partition by [case] 
              order by category) seq 
        from yourtable 
       ) d 
     FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'') 

    set @query = 'SELECT [case],' + @cols + ' 
     from 
     (
      SELECT [case], category, 
      ''cat''+ 
       cast(row_number() over(partition by [case] 
            order by category) as varchar(10)) seq 
      FROM yourTable 
     ) x 
     pivot 
     (
      max(category) 
      for seq in (' + @cols + ') 
     ) p ' 

    execute sp_executesql @query; 

的輸出是不錯的,它是我所需要的格式。

CASE CAT1 CAT2 CAT3 
1  abc xx xyx 
2  asdf ghj (null) 
3  dfgh (null) (null) 

但是,我還需要添加額外的列到表中。修改後的表格如下所示,但我不確定如何將其添加到QUOTENAME中。

CREATE TABLE yourtable 
    ([case] int, [category] varchar(4), [status] varchar(4)) 
    ; 

    INSERT INTO yourtable 
    ([case], [category], [status]) 
    VALUES 
    (1, 'xx', '00'), 
    (1, 'xyx', '01'), 
    (1, 'abc', '00'), 
    (2, 'ghj', '01'), 
    (2, 'asdf', '00'), 
    (3, 'dfgh', '01') 
    ; 

這怎麼辦?我應該添加一個額外的QUOTENAME命令嗎?結果應該是:

CASE CAT1 status1 CAT2  status2  CAT3  status3 
    1  abc  00   xx   00   xyx  01 
    2  asdf 00   ghj   01  (null) (null) 
    3  dfgh 01  (null)  (null)  (null) (null) 

回答

3

因爲現在你要樞兩列,可以先unpivot的的categorystatus列與多行一列。

有幾種不同的方式可以取消數據傳輸,可以使用UNPIVOT或CROSS APPLY。基本語法爲:

select [case], 
    col+cast(seq as varchar(10)) seq, 
    value 
from 
(
    SELECT [case], status, category, 
    row_number() over(partition by [case] 
         order by status) seq 
    FROM yourTable 
) d 
cross apply 
(
    select 'cat', category union all 
    select 'status', status 
) c (col, value) 

SQL Fiddle with Demo這將您的多列數據轉換成的東西,看起來像這樣:

| CASE |  SEQ | VALUE | 
|------|---------|-------| 
| 1 | cat1 | xx | 
| 1 | status1 | 00 | 
| 1 | cat2 | abc | 
| 1 | status2 | 00 | 
| 1 | cat3 | xyx | 
| 1 | status3 | 01 | 
| 2 | cat1 | asdf | 
| 2 | status1 | 00 | 

一旦數據以這種格式,那麼你可以申請的PIVOT功能。

SELECT [case], cat1, status1, cat2, status2, cat3, status3 
FROM 
(
    select [case], 
    col+cast(seq as varchar(10)) seq, 
    value 
    from 
    (
    SELECT [case], status, category, 
     row_number() over(partition by [case] 
         order by status) seq 
    FROM yourTable 
) d 
    cross apply 
    (
    select 'cat', category union all 
    select 'status', status 
) c (col, value) 
) x 
PIVOT 
(
    max(value) 
    for seq in (cat1, status1, cat2, status2, cat3, status3) 
)p; 

SQL Fiddle with Demo

然後你就可以將其轉換爲動態SQL:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(col+cast(seq as varchar(10))) 
        from 
        (
         select row_number() over(partition by [case] 
               order by category) seq 
         from yourtable 
        ) d 
        cross apply 
        (
         select 'cat', 1 union all 
         select 'status', 2 
        ) c (col, so) 
        group by seq, col, so 
        order by seq, so 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT [case],' + @cols + ' 
      from 
      (
       select [case], 
       col+cast(seq as varchar(10)) seq, 
       value 
       from 
       (
       SELECT [case], status, category, 
        row_number() over(partition by [case] 
            order by status) seq 
       FROM yourTable 
      ) d 
       cross apply 
       (
       select ''cat'', category union all 
       select ''status'', status 
      ) c (col, value) 
      ) x 
      pivot 
      (
       max(value) 
       for seq in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 

SQL Fiddle with Demo最終的結果將是:

| CASE | CAT1 | STATUS1 | CAT2 | STATUS2 | CAT3 | STATUS3 | 
|------|------|---------|--------|---------|--------|---------| 
| 1 | xx |  00 | abc |  00 | xyx |  01 | 
| 2 | asdf |  00 | ghj |  01 | (null) | (null) | 
| 3 | dfgh |  01 | (null) | (null) | (null) | (null) | 
+1

顯然,還有我們之間的主人。 ;) – riverdog