如何基于值将行转换为列

时间:2019-01-21 20:58:43

标签: sql sql-server tsql pivot-table

我在一个表中有以下数据,该表中的每个组在两行中包含两个ON / OFF值。我想根据状态将行转换为新列“ Col1 => Col1_Status_ON / OFF”新名称

这是详细信息:

====================================================
| Group  | DateTime    | Status | Col1   |  Col2   |
====================================================
| Group1 | 01-Jan-2019 |  ON    | 101    |  102    |
| Group1 | 01-Jan-2019 |  OFF   | 201    |  202    |
| Group2 | 01-Jan-2019 |  ON    | 301    |  302    |
| Group2 | 01-Jan-2019 |  OFF   | 401    |  402    |
| Group3 | 01-Jan-2019 |  ON    | 501    |  502    |
| Group4 | 01-Jan-2019 |  OFF   | 601    |  602    |
====================================================

我要返回的查询如下

    =======================================================================================
        | Group  | DateTime   |Col1_Satus_ON|Col1_Satus_OFF|Col2_Status_ON|Col2_Status_OFF|
    =======================================================================================
        | Group1 | 01-Jan-2019|   101       |   201        |    102       |   202         |
        | Group2 | 01-Jan-2019|   301       |   401        |    302       |   402         |
        | Group3 | 01-Jan-2019|   501       |   601        |    502       |   602         |        
    =======================================================================================

下面是生成表数据的SQL。

DROP TABLE IF EXISTS dbo.#MyTable;
SELECT CONVERT(VARCHAR(100),'')[Group], GETDATE()[DateTime],
       CONVERT(VARCHAR(100),'')[Status],(0)[Col1],(0)[Col2] 
       INTO #MyTable WHERE 1=2;

INSERT INTO #MyTable ([Group],[Datetime],[Status],[Col1],[Col2])
    SELECT 'Group1','01-Jan-2019 01:02:03','ON' ,101,102 UNION
    SELECT 'Group1','01-Jan-2019 01:02:03','OFF',201,202 UNION
    SELECT 'Group2','01-Jan-2019 01:02:03','ON' ,301,302 UNION
    SELECT 'Group2','01-Jan-2019 01:02:03','OFF',401,402 UNION
    SELECT 'Group3','01-Jan-2019 01:02:03','ON' ,501,502 UNION
    SELECT 'Group3','01-Jan-2019 01:02:03','OFF',601,602;

SELECT * FROM #MyTable;

请建议查询

2 个答案:

答案 0 :(得分:3)

您可以使用条件聚合:

mapActions

db<>fiddle demo

答案 1 :(得分:3)

这是人们建议的动态工作枢纽

示例

Declare @UnPiv varchar(max),@SQL varchar(max)
Set @UnPiv = Stuff(( Select ','+quotename(name)
                      From  sys.dm_exec_describe_first_result_set(N'Select top 1 * from #MyTable',null,null )  A
                      Where Name not in ('Group','DateTime','Status')
                      For XML Path('')),1,1,'')

Set @SQL   = Stuff(( Select ','+quotename(name+Suffix)
                      From  sys.dm_exec_describe_first_result_set(N'Select top 1 * from #MyTable',null,null )  A
                      Cross Join ( values ('_Status_ON')
                                         ,('_Status_OFF')
                                 ) B(Suffix)
                       Where Name not in ('Group','DateTime','Status')
                       For XML Path('')),1,1,'')

Select @SQL = '
Select *
 From  (
        Select [Group]
              ,[DateTime]
              ,Item = concat(Item,''_Status_'',Status)
              ,Value
         From  (
                 Select * From #MyTable Unpivot (Value for Item in ('+@UnPiv+')) UnPiv
               ) A
       ) src
 Pivot (max(Value) for Item in ('+@SQL+') ) pvt
'
--Print @SQL
Exec(@SQL)

返回

enter image description here