将可变数量的行PIVOT到列

use*_*103 3 sql t-sql sql-server pivot

我目前正试图将一些行PIVOT到列.问题是我并不总是知道有多少行可用.我们来看一个例子:

Values_Table                         Columns_Table
------------                         -----------
ID                                   ID
ColumnsTableID                       GroupID
Value                                ColumnName
Run Code Online (Sandbox Code Playgroud)

结果"

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
Run Code Online (Sandbox Code Playgroud)

SQL FIDDLE STATIC枢轴的示例.我正在努力实现一个动态的支点 - http://sqlfiddle.com/#!3/2be82/1

所以,这就是我的困境:我希望能够在此场景中基于GroupID来旋转未知数量的列.

我希望能够将GroupID 3中的所有行PIVOT分成列.我需要在不知道groupID 3中有多少行的情况下执行此操作.

数据库的设计是一成不变的,所以我对此无能为力.我所能做的只是与我所拥有的一起工作:(

那就是说 - 在这个例子中,有没有人对如何完成将未知行数分成列的任务提出任何建议?

Tar*_*ryn 5

如果您不打算提前知道这些值,那么您将需要查看使用动态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;
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.对于3的groupid,结果将是:

|   KENTROSAURUS |     RAPTOR |     TREX |    TRICERATOPS |
| whatisthiseven | Itsaraptor | Jurassic | landbeforetime |
|         (null) |       zomg |     Park |         (null) |
Run Code Online (Sandbox Code Playgroud)