I'm currently attempting to PIVOT some rows to columns. The problem is that I don't always know how many rows will be available. Let's look at an example:
我目前正在尝试将一些行转向列。问题是,我并不总是知道有多少行可用。让我们看一个例子:
Values_Table Columns_Table
------------ -----------
ID ID
ColumnsTableID GroupID
Value ColumnName
RESULTS"
结果”
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 EXAMPLE of a STATIC pivot. I am trying to achieve a dynamic pivot - http://sqlfiddle.com/#!3/2be82/1
一个静态轴心的SQL小提琴示例。我正在尝试实现一个动态的pivot - http://sqlfiddle.com/#
So, here is my dilemma: I want to be able to pivot an unknown number of columns based on, in this scenario, the GroupID.
所以,这里是我的困境:我希望能够在这个场景中,基于,GroupID,基于一个未知的列。
I want to be able to PIVOT, for example, all the rows in GroupID 3 into columns. I would need to do this without knowing how many rows are in groupID 3.
例如,我希望能够将GroupID 3中的所有行转换为列。我需要这样做,而不知道groupID 3中有多少行。
The design of the database is set in stone, so I can't do anything about that. All I can do is work with what I have :(
数据库的设计是一成不变的,所以我对此无能为力。我所能做的就是用我所拥有的去工作
So, that said- does anyone have any suggestions on how to accomplish this task of PIVOTing an unknown number of rows into columns based on, in this example, the groupID?
那么,有人有什么建议来完成这个任务吗?在这个例子中,根据groupID,将未知的行转换成列?
1 个解决方案
#1
5
If you are not going to know the values ahead of time, then you will need to look at using dynamic SQL. This will create a SQL String that will be executed, this is required because the list of columns must be known when the query is run.
如果您不打算提前知道这些值,那么您需要考虑使用动态SQL。这将创建将要执行的SQL字符串,这是必需的,因为在运行查询时必须知道列的列表。
The code will be similar to:
守则将类似于:
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;
See SQL Fiddle with Demo. For groupid of 3, then the result will be:
参见SQL小提琴演示。对于groupid为3,则结果为:
| KENTROSAURUS | RAPTOR | TREX | TRICERATOPS |
| whatisthiseven | Itsaraptor | Jurassic | landbeforetime |
| (null) | zomg | Park | (null) |
#1
5
If you are not going to know the values ahead of time, then you will need to look at using dynamic SQL. This will create a SQL String that will be executed, this is required because the list of columns must be known when the query is run.
如果您不打算提前知道这些值,那么您需要考虑使用动态SQL。这将创建将要执行的SQL字符串,这是必需的,因为在运行查询时必须知道列的列表。
The code will be similar to:
守则将类似于:
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;
See SQL Fiddle with Demo. For groupid of 3, then the result will be:
参见SQL小提琴演示。对于groupid为3,则结果为:
| KENTROSAURUS | RAPTOR | TREX | TRICERATOPS |
| whatisthiseven | Itsaraptor | Jurassic | landbeforetime |
| (null) | zomg | Park | (null) |