簡體   English   中英

SQL透視還是轉置還是…列到行?

[英]SQL Pivoting or Transposing or … column to row?

我有一個問題,在SQLfiddle中看起來更好: http ://www.sqlfiddle.com/#!3 / dffa1 /2

我為每個具有datestamp和測試結果的用戶提供了一個具有多行的表,我想將其轉置或旋轉為一行結果,如下所示,其中每個用戶都列出了所有時間和值結果:

USERID PSA1_time PSA1_result PSA2_time PSA2_result PSA3_time PSA3_result ...


1      1999-.... 2           1998...   4           1999...   6

3      1992...   4           1994      6

4      2006 ...  8

下表:

CREATE TABLE yourtable
    ([userid] int, [Ranking] int,[test] varchar(3), [Date] datetime, [result] int)
; 

INSERT INTO yourtable
    ([userid], [Ranking],[test], [Date], [result])
VALUES
    ('1', '1', 'PSA', 1997-05-20, 2),
    ('1', '2','PSA', 1998-05-07, 4),
    ('1', '3','PSA', 1999-06-08, 6),
    ('1', '4','PSA', 2001-06-08, 8),
    ('1', '5','PSA', 2004-06-08, 0),
        ('3', '1','PSA', 1992-05-07, 4),
    ('3', '2','PSA', 1994-06-08, 6),
    ('4', '1','PSA', 2006-06-08, 8)
;

由於您希望將PIVOT列為兩列,因此我的建議是先取消dateresult列的透視圖,然后再應用PIVOT函數。

取消透視過程將兩列dateresult轉換為多行:

select userid, 
  col = test +'_'+cast(ranking as varchar(10))+'_'+ col,
  value
from yourtable t1
cross apply
(
  select 'time', convert(varchar(10), date, 120) union all
  select 'result', cast(result as varchar(10))
) c (col, value)

參見演示 這將為您提供結果:

| USERID |          COL |      VALUE |
--------------------------------------
|      1 |   PSA_1_time | 1997-05-20 |
|      1 | PSA_1_result |          2 |
|      1 |   PSA_2_time | 1998-05-07 |
|      1 | PSA_2_result |          4 |
|      1 |   PSA_3_time | 1999-06-08 |

現在您已經有了這種格式的數據,那么您就可以應用數據透視獲取col每個項目的max / min

如果列數有限,則可以對查詢進行硬編碼:

select *
from
(
  select userid, 
    col = test +'_'+cast(ranking as varchar(10))+'_'+ col,
    value
  from yourtable t1
  cross apply
  (
    select 'time', convert(varchar(10), date, 120) union all
    select 'result', cast(result as varchar(10))
  ) c (col, value)
) d
pivot
(
  max(value)
  for col in (PSA_1_time, PSA_1_result,
              PSA_2_time, PSA_2_result,
              PSA_3_time, PSA_3_result,
              PSA_4_time, PSA_4_result,
              PSA_5_time, PSA_5_result)
) piv;

參見帶有演示的SQL Fiddle

如果您有未知的列,則需要使用動態SQL:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(test +'_'+cast(ranking as varchar(10))+'_'+ col) 
                    from yourtable
                    cross apply
                    (
                      select 'time', 1 union all
                      select 'result', 2
                    ) c (col, so)
                    group by test, ranking, col, so
                    order by Ranking, so
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT userid,' + @cols + ' 
            from 
            (
              select userid, 
                col = test +''_''+cast(ranking as varchar(10))+''_''+ col,
                value
              from yourtable t1
              cross apply
              (
                select ''time'', convert(varchar(10), date, 120) union all
                select ''result'', cast(result as varchar(10))
              ) c (col, value)
            ) x
            pivot 
            (
                max(value)
                for col in (' + @cols + ')
            ) p '

execute sp_executesql @query;

請參閱帶有演示的SQL Fiddle 這兩個版本都會給出結果:

| USERID | PSA_1_TIME | PSA_1_RESULT | PSA_2_TIME | PSA_2_RESULT | PSA_3_TIME | PSA_3_RESULT | PSA_4_TIME | PSA_4_RESULT | PSA_5_TIME | PSA_5_RESULT |
------------------------------------------------------------------------------------------------------------------------------------------------------
|      1 | 1997-05-20 |            2 | 1998-05-07 |            4 | 1999-06-08 |            6 | 2001-06-08 |            8 | 2004-06-08 |            0 |
|      3 | 1992-05-07 |            4 | 1994-06-08 |            6 |     (null) |       (null) |     (null) |       (null) |     (null) |       (null) |
|      4 | 2006-06-08 |            8 |     (null) |       (null) |     (null) |       (null) |     (null) |       (null) |     (null) |       (null) |

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM