SQL - 将多行数据转换为单行

daw*_*onz 8 sql sql-server sql-server-2005

我有一个类似于这里的表:

SetId       AppCode       AppEventId       EventId       FieldId       ValueData
2012/2013     1000         361616             16            1            UNI     
2012/2013     1000         361616             16            2            Isolation
2012/2013     1000         361616             16            3            DN
2012/2013     1050         378194             16            1            BUL
2012/2013     1050         378194             16            2            Isolation
2012/2013     1050         378194             16            3            RD
Run Code Online (Sandbox Code Playgroud)

我希望能够在拥有相同的AppCode时将所有数据组合在一起.

看起来像这样:

SetId       AppCode       AppEventId       EventId       ValueData1      ValueData2      ValueData3
2012/2013     1000         361616             16            UNI            Isolation        DN
2012/2013     1050         378194             16            BUL            Isolation        RD
Run Code Online (Sandbox Code Playgroud)

bvr*_*bvr 16

试试这个

  SELECT SetId, AppCode, AppEventId, EventId 
  ,max(CASE WHEN FieldId = 1 THEN ValueData END) AS ValueData1
  ,max(CASE WHEN FieldId = 2 THEN ValueData END) AS ValueData2
  ,max(CASE WHEN FieldId = 3 THEN ValueData END) AS ValueData3
   FROM Table_Name 
   GROUP BY SetId,AppCode,AppEventId,EventId 
Run Code Online (Sandbox Code Playgroud)


Tar*_*ryn 7

这可以通过应用从SQL Server 2005开始提供的PIVOT函数来完成.

如果您要将已知或设定数量的值转换为列,则可以对查询进行硬编码:

select setid, appcode, appeventid,
  eventid,
  ValueData1, ValueData2, ValueData3
from
(
  select setid, appcode, appeventid,
    eventid,
    'ValueData'+cast(FieldId as varchar(10)) FieldId, 
    ValueData
  from yt
) d
pivot
(
  max(ValueData)
  for FieldId in (ValueData1, ValueData2, ValueData3)
) piv;
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.

但是如果你有一个未知数量的值,那么你将需要使用动态SQL:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('ValueData'+cast(FieldId as varchar(10))) 
                    from yt
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT setid, appcode, appeventid,
                  eventid,' + @cols + ' 
            from 
            (
                select setid, appcode, appeventid,
                  eventid,
                  ''ValueData''+cast(FieldId as varchar(10)) FieldId, 
                  ValueData
                from yt
            ) x
            pivot 
            (
                max(ValueData)
                for FieldId in (' + @cols + ')
            ) p '

execute(@query);
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.两个查询都给出相同的结果:

|     SETID | APPCODE | APPEVENTID | EVENTID | VALUEDATA1 | VALUEDATA2 | VALUEDATA3 |
-------------------------------------------------------------------------------------
| 2012/2013 |    1000 |     361616 |      16 |        UNI |  Isolation |         DN |
| 2012/2013 |    1050 |     378194 |      16 |        BUL |  Isolation |         RD |
Run Code Online (Sandbox Code Playgroud)