如何在SqlServer中使用PIVOT将行转换为列

时间:2015-01-28 12:46:20

标签: sql sql-server

我有这张桌子:

Dimension   Meaning
---------   -------
Browser     IE9
Browser     IE10
Module      Ticket
Module      Board
OS          Windows
OS          Ios
OS          Linux

我想要所有可能的组合:

Browser     Module     OS
-------     ------     ------
IE9         Ticket     Windows
IE9         Ticket     Ios
IE9         Ticket     Linux
IE10        Board      Windows
IE10        Board      Ios
IE10        Board      Linux

等等......源表不会增长太多,所以不需要花哨的性能,我也不介意对列进行硬编码

我目前正在使用此查询,但我只获得一行:

SELECT [Browser],[Module],[Os] FROM 
         (
            SELECT Meaning, Dimension 
            FROM [Mits].[dbo].[ToolHintValues]
         ) x
         pivot 
         (
            MAX(Meaning)
            FOR Dimension IN ([Browser],[Module],[Os])
         ) p 

有关如何获得所有组合的任何帮助? 提前致谢

更新: 这是仍然返回一行的动态sql版本:

DECLARE @cols AS NVARCHAR(MAX)
DECLARE @query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(Dimension) 
                from [dbo].[ToolHintValues]
                group by Dimension
                order by Dimension
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')
set @query = N'SELECT ' + @cols + N' FROM 
         (
            SELECT Meaning, Dimension 
            FROM [dbo].[ToolHintValues]
         ) x
         pivot 
         (
            MAX(Meaning)
            FOR Dimension IN (' + @cols + N')
         ) p '
SELECT @query
exec sp_executesql @query;

1 个答案:

答案 0 :(得分:0)

如果您知道维度是什么,可以使用cross join

select b.meaning as browser, m.meaning as module, o.meaning as os
from (select distinct meaning from thistable where dimension = 'browser'
     ) b cross join
     (select distinct meaning from thistable where dimension = 'module'
     ) m cross join
     (select distinct meaning from thistable where dimension = 'os'
     ) o;

如果您不了解所有维度,那么您将不得不使用动态SQL做一些更复杂的事情。 SQL查询返回一组固定的列;要有一个变量号,你需要动态SQL。