我需要使用以下结构在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功能。
谢谢!
答案 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来构建要透视的列列表。我演示了静态版本,因为它可以更容易地将代码转换为动态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)
两者都给出结果:
| 1 | 2 | 3 |
-----------------------------
| Orange | Apple | Banana |
| Grape | Corn | Lemon |
| Tomato | Lettuce | Onion |