我正在尝试将一些行PIVOT到列。问题是我并不总是知道有多少行可用。我们来看一个例子:
Values_Table Columns_Table
------------ -----------
ID ID
ColumnsTableID GroupID
Value ColumnName
结果“
Columns_Table
---------------
ID | GroupID | ColumnName
---------------------------------
0 1 Cats
1 1 Dogs
2 1 Birds
3 2 Pontiac
4 2 Ford
5 3 Trex
6 3 Raptor
7 3 Triceratops
8 3 Kentrosaurus
SQL FIDDLE STATIC枢轴的示例。我正在努力实现动态支点 - http://sqlfiddle.com/#!3/2be82/1
所以,这就是我的困境:我希望能够在此场景中基于GroupID来旋转未知数量的列。
我希望能够将GroupID 3中的所有行PIVOT分成列。我需要在不知道groupID 3中有多少行的情况下执行此操作。
数据库的设计是一成不变的,所以我对此无能为力。我所能做的只是与我所拥有的一起工作:(
那么,那么说 - 在这个例子中,有没有人对如何完成将未知行数分成列的任务提出任何建议?
答案 0 :(得分:5)
如果您不提前知道这些值,那么您需要查看使用dynamic SQL。这将创建一个将要执行的SQL字符串,这是必需的,因为在运行查询时必须知道列的列表。
代码类似于:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@groupid as int
set @groupid = 3
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(GroupName)
from Columns_Table
where groupid = @groupid
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT ' + @cols + '
from
(
SELECT B.GroupName, A.Value
, row_number() over(partition by a.ColumnsTableID
order by a.Value) seq
FROM Values_Table AS A
INNER JOIN Columns_Table AS B
ON A.ColumnsTableID = B.ID
where b.groupid = '+cast(@groupid as varchar(10))+'
) p
pivot
(
min(P.Value)
for P.GroupName in (' + @cols + ')
) p '
execute sp_executesql @query;
见SQL Fiddle with Demo。对于groupid为3,则结果为:
| KENTROSAURUS | RAPTOR | TREX | TRICERATOPS |
| whatisthiseven | Itsaraptor | Jurassic | landbeforetime |
| (null) | zomg | Park | (null) |