【问题标题】:PIVOTing variable number of rows to columns将可变数量的行旋转到列
【发布时间】:2013-09-23 10:09:27
【问题描述】:

我目前正在尝试将某些行 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 示例。我正在尝试实现动态支点 - http://sqlfiddle.com/#!3/2be82/1

因此,这是我的两难境地:在这种情况下,我希望能够基于 GroupID 来旋转未知数量的列。

我希望能够 PIVOT,例如,将 GroupID 3 中的所有行转换为列。我需要在不知道 groupID 3 中有多少行的情况下执行此操作。

数据库的设计是一成不变的,所以我对此无能为力。我所能做的就是利用我所拥有的:(

那么,有人对如何完成这项任务有任何建议吗?在此示例中,基于 groupID 将未知数量的行 PIVOTing 到列中?

【问题讨论】:

    标签: sql sql-server tsql pivot


    【解决方案1】:

    如果您不打算提前知道这些值,那么您需要查看使用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) |
    

    【讨论】:

    • 太完美了!非常感谢您的回答 =D 一如既往,准点!
    • 只是出于好奇,您能想出一种方法,在不知道列名是什么的情况下提前将其放入临时表中吗?
    • @user1548103 您可以在新表中使用 select。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-01
    • 2016-06-16
    • 2013-06-21
    • 2019-08-10
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多