在没有GROUPING BY的情况下在SQL Server中透视或转置表

时间:2013-03-06 23:14:41

标签: sql-server pivot transpose

我需要使用以下结构在SQL Server中透视表:

CREATE TABLE table1 (
    ColumnNumber int,
    RowNumber int,
    CellData nvarchar(50)
)

INSERT INTO table1 VALUES
(1, 1, 'Orange'),
(2, 1, 'Apple'),
(3, 1, 'Banana'),
(1, 2, 'Grape'),
(2, 2, 'Corn'),
(3, 2, 'Lemon'),
(1, 3, 'Tomato'),
(2, 3, 'Lettuce'),
(3, 3, 'Onion')

我需要结果表看起来像这样:

enter image description here

因此ColumnNumber行中的单元格现在是结果表格的列名称。最难的部分是不同列数的数量是可变的(所以现在我们有3个列号,但明天可能有6个或10个)。

我一直在关注PIVOT功能,但所有示例都包含GROUP BY,而且,正如您在此处所看到的,我需要更像是"转置" excel功能。

谢谢!

1 个答案:

答案 0 :(得分:6)

这可以使用PIVOT功能完成。 GROUP BY将起作用,因为您有一个指示符,使每个行都不同。对于您的数据,指标是rowNumber列。

如果您有一定数量的列,那么您将需要使用静态数据透视表对它们进行硬编码。代码将类似于以下内容:

select [1], [2], [3]
from
(
  select colNumber, RowNumber, CellData
  from yourtable
) src
pivot
(
  max(CellData)
  for colnumber in ([1], [2], [3])
) piv;

请参阅SQL Fiddle with Demo

在您的情况下,您声明您将拥有未知数量的列。如果这是您的情况,那么您将需要使用动态SQL来构建要透视的列列表。我演示了静态版本,因为它可以更容易地将代码转换为动态SQL。

动态sql版本的关键是获取列列表,这是通过查询表并创建列名称字符串来完成的。这是使用FOR XML PATH

完成的
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(colNumber) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

然后将此列表添加到您生成的查询字符串中,最终代码为:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(colNumber) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ' + @cols + ' 
             from 
             (
                select colNumber, rowNumber, CellData
                from yourtable
            ) x
            pivot 
            (
                min(CellData)
                for colNumber in (' + @cols + ')
            ) p '

execute(@query)

请参阅SQL Fiddle with Demo

两者都给出结果:

|      1 |       2 |      3 |
-----------------------------
| Orange |   Apple | Banana |
|  Grape |    Corn |  Lemon |
| Tomato | Lettuce |  Onion |