3

我需要在 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')

我需要结果表如下所示:

在此处输入图像描述

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

我一直在研究 PIVOT 函数,但所有示例都包含GROUP BY, 并且,正如您在此处看到的,我需要更像“转置”excel 函数的东西。

谢谢 !!

4

1 回答 1

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 |
于 2013-03-06T23:22:39.820 回答