2012-12-05 46 views
1

是否存在將TABLE_1轉換爲預期結果集的T-SQL(SQL Server 2008R2)查詢?T-SQL:從行到列但不是實際的樞軸

TABLE_1

+----------+-------------------------+---------+------+ 
| IdDevice | Timestamp    | M300 | M400 | 
+----------+-------------------------+---------+------+ 
| 3  | 2012-12-05 16:29:51.000 | 2357,69 | 520 | 
| 6  | 2012-12-05 16:29:51.000 | 1694,81 | 470 | 
| 1  | 2012-12-05 16:29:51.000 | 2046,33 | 111 | 
+----------+-------------------------+---------+------+ 

預期的結果集

+-------------------------+---------+--------+---------+--------+---------+--------+ 
|  Timestamp  | 3_M300 | 3_M400 | 6_M300 | 6_M400 | 6_M300 | 6_M400 | 
+-------------------------+---------+--------+---------+--------+---------+--------+ 
| 2012-12-05 16:29:51.000 | 2357,69 | 520 | 1694,81 | 470 | 2046,33 | 111 | 
+-------------------------+---------+--------+---------+--------+---------+--------+ 
+0

對於結果的最後兩列你的意思了'6'到前言名稱或它應該是'1'?你知道所有你想改變的id設備還是未知的? – Taryn

回答

2

這仍然是一個PIVOT查詢,但你以前PIVOT,必須執行列的UNPIVOT

首先,您執行UNPIVOT,它將採用當前的多個列並將它們轉換爲兩列 - 一列帶有值,另一列帶有列名。爲UNPIVOT的關鍵是數據類型是相同的,所以在子查詢我cast任何列相同的數據類型:

select timestamp, 
    value, cast(iddevice as varchar(10)) + '_'+col as col 
    from 
    (
    select iddevice, 
     timestamp, 
     cast(m300 as varchar(10)) m300, 
     cast(m400 as varchar(10)) m400 
    from yourtable 
) src 
    unpivot 
    (
    value 
    for col in (m300, m400) 
) unpiv 

SQL Fiddle with Demo

結果:

|      TIMESTAMP | VALUE | COL | 
------------------------------------------------------ 
| December, 05 2012 16:29:51+0000 | 2357,69 | 3_m300 | 
| December, 05 2012 16:29:51+0000 |  520 | 3_m400 | 
| December, 05 2012 16:29:51+0000 | 1694,81 | 6_m300 | 
| December, 05 2012 16:29:51+0000 |  470 | 6_m400 | 
| December, 05 2012 16:29:51+0000 | 2046,33 | 1_m300 | 
| December, 05 2012 16:29:51+0000 |  111 | 1_m400 | 

一旦你完成不透光,那麼你可以應用PIVOT功能:

select * 
from 
(
    select timestamp, 
    value, cast(iddevice as varchar(10)) + '_'+col as col 
    from 
    (
    select iddevice, 
     timestamp, 
     cast(m300 as varchar(10)) m300, 
     cast(m400 as varchar(10)) m400 
    from yourtable 
) src 
    unpivot 
    (
    value 
    for col in (m300, m400) 
) unpiv 
) src1 
pivot 
(
    max(value) 
    for col in ([3_m300], [3_m400], 
       [6_m300], [6_m400], 
       [1_m300], [1_m400]) 
) piv 

SQL Fiddle with Demo

結果:

|      TIMESTAMP | 3_M300 | 3_M400 | 6_M300 | 6_M400 | 1_M300 | 1_M400 | 
-------------------------------------------------------------------------------------------- 
| December, 05 2012 16:29:51+0000 | 2357,69 | 520 | 1694,81 | 470 | 2046,33 | 111 | 

如果你有IdDevices一個未知的數字,要轉換成列,那麼你可以使用動態SQL:

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

select @cols = STUFF((SELECT DISTINCT ',' 
         + quotename(cast(t.IdDevice as varchar(10)) +'_' 
            +c.name) 
        from yourtable t 
        cross apply sys.columns as C 
        where C.object_id = object_id('yourtable') and 
         C.name not in ('IdDevice', 'Timestamp') 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 


set @query = 'SELECT timestamp,' + @cols + ' from 
      (
       select timestamp, 
       value, cast(iddevice as varchar(10)) + ''_''+col as col 
       from 
       (
       select iddevice, 
        timestamp, 
        cast(m300 as varchar(10)) m300, 
        cast(m400 as varchar(10)) m400 
       from yourtable 
      ) src 
       unpivot 
       (
       value 
       for col in (m300, m400) 
      ) unpiv 
      ) x 
      pivot 
      (
       max(value) 
       for col in (' + @cols + ') 
      ) p ' 

execute(@query) 

SQL Fiddle with Demo

編輯,如果您需要每個m值的總計字段,那麼你可以使用:

select timestamp, 
    [3_m300], [3_m400], 
    [6_m300], [6_m400], 
    [1_m300], [1_m400], 
    [1_m300] + [3_m300] + [6_m300] Total_m300, 
    [1_m400] + [3_m400] + [6_m400] Total_m400 
from 
(
    select timestamp, 
    value, cast(iddevice as varchar(10)) + '_'+col as col 
    from 
    (
    select iddevice, 
     timestamp, 
     m300, 
     m400 
    from yourtable 
) src 
    unpivot 
    (
    value 
    for col in (m300, m400) 
) unpiv 
) src1 
pivot 
(
    sum(value) 
    for col in ([3_m300], [3_m400], 
       [6_m300], [6_m400], 
       [1_m300], [1_m400]) 
) piv 

SQL Fiddle with Demo

+0

你的回答非常好。 我需要進一步的步驟:在公式中使用列。例如:1_M300 + 3_M300 + 6_300(+是一個SUM而不是串接)。 – Matte

+0

@Matte看我的編輯,或者我的演示 - http://sqlfiddle.com/#!3/cfeb5/2 – Taryn

+0

好的,回答接受。你絕對是一名樞軸大師。 – Matte