5

我有一张这样的数据表

create table temp
(
    colName varchar(50),
    name varchar(50),
    icon varchar(150),
    totalcount int
)

insert into temp values ('Eng1', 'Following', 'followingicon.png', 1564)

insert into temp values ('Eng2','Total Followers', 'followericon.png', 500)

insert into temp values ('Eng3','Direct Messages', 'messageicon.png', 800)

如何选择并使数据显示为

最终结果

Eng1、Eng2 和 Eng3 为列标题

这是我到目前为止得到的,但它只做第一级。我需要获得所有三个级别

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

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.colName) 
            FROM temp c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT ' + @cols + ' from 
            (
                select colName              
                    , totalcount
                from temp
           ) x
            pivot 
            (
                 max( totalcount)
                for colName in (' + @cols + ')               
            ) p'

execute(@query)

我正在使用 SQL Server 2008。

谢谢您的帮助!

4

2 回答 2

3

这是一种方法:

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

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.colName) 
            FROM #temp c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')


SET @query = 'SELECT ' + @cols + ' FROM 
            (
                SELECT y.*
                FROM #Temp t
                CROSS APPLY 
                (
                    VALUES (t.colname,CONVERT(VARCHAR(150),name),''name''),
                           (t.colname,icon,''icon''),
                           (t.colname,CONVERT(VARCHAR(150),totalcount),''totalcount'')
                ) y (colName, value, Data)
           ) x
            PIVOT 
            (
                 MAX(Value)
                FOR colName IN (' + @cols + ')               
            ) p'

EXECUTE(@query)
于 2013-09-05T19:39:23.607 回答
3

当您使用动态 SQL 时,我的建议是首先编写查询的硬编码版本以使逻辑正确,然后将其转换为动态 SQL。

要获得结果,您必须先查看取消旋转name,icontotalcount列,然后您可以应用旋转来创建新列。您可以使用 UNPIVOT 函数或 CROSS APPLY 将列转换为行。将数据从列转换为行的查询将是:

select colname, origCol, value
from temp
cross apply
(
  select 'name', name union all
  select 'icon', icon union all
  select 'totalcount', cast(totalcount as varchar(50))
) c (origCol, value)

请参阅演示。这将为您提供以下格式的数据:

| COLNAME |    ORIGCOL |             VALUE |
|    Eng1 |       name |         Following |
|    Eng1 |       icon | followingicon.png |
|    Eng1 | totalcount |              1564 |
|    Eng2 |       name |   Total Followers |

然后您可以将 PIVOT 函数应用于您的新colname值:

select Eng1, Eng2, Eng3
from 
(
  select colname, origCol, value
  from temp
  cross apply
  (
    select 'name', name union all
    select 'icon', icon union all
    select 'totalcount', cast(totalcount as varchar(50))
  ) c (origCol, value)
) src
pivot
(
  max(value)
  for colname in (Eng1, Eng2, Eng3)
) piv

请参阅SQL Fiddle with Demo。正如我所说,您需要一个动态版本,因此现在您的逻辑正确,您可以将其转换为动态 SQL 查询:

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

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.colName) 
            FROM temp c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT ' + @cols + ' 
          from 
          (
            select colname, origCol, value
            from temp
            cross apply
            (
              select ''name'', name union all
              select ''icon'', icon union all
              select ''totalcount'', cast(totalcount as varchar(50))
            ) c (origCol, value)
           ) x
            pivot 
            (
                 max(value)
                for colName in (' + @cols + ')               
            ) p'

execute sp_executesql @query;

请参阅SQL Fiddle with Demo。这将给出一个结果:

|              ENG1 |             ENG2 |            ENG3 |
| followingicon.png | followericon.png | messageicon.png |
|         Following |  Total Followers | Direct Messages |
|              1564 |              500 |             800 |
于 2013-09-05T19:45:25.283 回答