0

我需要将行转换为列,但我不想使用 PIVOT,因为它需要预先定义列(我的列将是动态的)。因此,解决方案是使用带有 PIVOT 的动态 SQL,但我不想使用动态 SQL,因为我想使用该 SQL 的结果与另一个静态 SQL 连接以生成不同的结果集。还有哪些其他选择?

这是我原来的 SQL 结果集:

EmpID|MonthYear|HoursWorked
10   |Jan 2013 |160
10   |Feb 2013 |150
10   |Mar 2013 |140
20   |Jan 2013 |130
20   |Feb 2013 |170
20   |Mar 2013 |155

转置的结果应该是这样的:

EmpID|Jan 2013|Feb 2013|Mar 2013
10   |160     |150     |140
20   |130     |170     |155
4

1 回答 1

0

不幸的是,如果您想将未知数量的值转换为列,则必须使用动态 SQL。要求在执行查询时知道新列,因此它必须是您正在执行的查询字符串的一部分。

您需要使用类似于以下内容的内容来获取要包含在查询中的列列表:

select @cols = STUFF((SELECT ',' + QUOTENAME(datename(m, monthyear) + ' ' 
                                         + cast(year(monthyear) as char(4))) 
                    from yourtable
                    group by monthyear
                    order by monthyear
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

然后您生成 PIVOT 结果的完整脚本将是:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(datename(m, monthyear) + ' ' 
                                         + cast(year(monthyear) as char(4))) 
                    from yourtable
                    group by monthyear
                    order by monthyear
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT empid,' + @cols + ' 
            from 
            (
                select empid, 
                  datename(m, monthyear) + '' '' 
                            + cast(year(monthyear) as char(4)) monthyear, 
                  hoursworked
                from yourtable
            ) src
            pivot 
            (
                sum(hoursworked)
                for monthyear in (' + @cols + ')
            ) p '

execute(@query);

请参阅带有演示的 SQL Fiddle

如果您想将此结果连接到其他表,那么您可以轻松地将 JOIN 包含在动态 SQL 字符串中,或​​者您可以将结果放入可以连接的临时表中。

于 2013-06-19T02:57:28.973 回答