使用 Unpivot 转换 SQL 表

Posted

技术标签:

【中文标题】使用 Unpivot 转换 SQL 表【英文标题】:Transforming an SQL table using Unpivot 【发布时间】:2015-06-17 20:40:16 【问题描述】:

如果我有一个具有以下结构的表

ID 名称 A1 A2 A3 B1 B2 B3

X----Y-----0---1---2---3---4---5(破折号只是在标题下推送值)

如何将其转换为以下内容:

ID 名称字母 1 2 3

X----Y---------A-----0-1-2

X---Y------------B-----3-4-5

【问题讨论】:

【参考方案1】:
SELECT id, name, 'A' letter, a1 1, a2 2, a3 3 from example_table
UNION
SELECT id, name, 'B' letter, b1 1, b2 2, b3 3 from example_table

我不确定1,2,3 是否可以用作列名;这可能依赖于 RDBMS。

【讨论】:

我不打算使用 1 2 3,它们现在只是示例名称。我会把我真正的列名放在最后:) 有没有更通用的方法?从 Sys cols 或其他什么获取列名?我必须将每一个硬编码到一个联合声明中......? 这对我来说听起来像是一个新问题。在那个问题中,我(或具有我一般知识水平的回答者)需要知道您使用的是哪个 RDBMS,并查看您希望将过程概括为的多个实例的示例。 也可能是相关的,无论您是绑定到纯 SQL 还是可以为您的项目使用过程语言(PL/SQL、TSQL 等)。【参考方案2】:

虽然我不认为这是一个可行的答案,但它可能会让您有所思考,因为它会在 sql server 中产生最终结果。

SELECT 
    upvt.id
    , upvt.name
    , left(label,1) AS letter
    , CASE
        WHEN left(label,1) = 'A' THEN MIN(value)
        WHEN left(label,1) = 'B' THEN MAX(value)
        END AS [1]
    , CASE
        WHEN left(label,1) = 'A' THEN MIN(value1)
        WHEN left(label,1) = 'B' THEN MAX(value1)
        END AS [2]
    , CASE
        WHEN left(label,1) = 'A' THEN MIN(value2)
        WHEN left(label,1) = 'B' THEN MAX(value2)
        END AS [3]
FROM example_table
UNPIVOT (
    value
    FOR label IN (a1,b1)
    ) upvt
INNER JOIN (
            SELECT 
                id
                , name
                , left(label1,1) AS letter
                , value1
            FROM example_table
            UNPIVOT (
                value1
                FOR label1 IN (a2,b2)
                ) upvt1 ) as b
    ON upvt.id = b.id
    AND upvt.name = b.name
INNER JOIN (
            SELECT 
                id
                , name
                , left(label2,1) AS letter
                , value2
            FROM example_table
            UNPIVOT (
                value2
                FOR label2 IN (a3,b3)
                ) upvt2 ) c
    ON upvt.id = c.id
    AND upvt.name = c.name
group by upvt.id, upvt.name, upvt.label

不完全是我所说的“生产就绪”。

【讨论】:

以上是关于使用 Unpivot 转换 SQL 表的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 使用 Pivot 和 UnPivot 实现行列转换

SQL Server 使用 Pivot 和 UnPivot 实现行列转换

SQL(横表和纵表)行列转换,PIVOT与UNPIVOT的区别和使用方法举例

使用 unpivot 将未知数量的列转换为行的动态 SQL 查询

将 UNPIVOT 从 SQL Server 转换为 Redshift

使用 UNPIVOT 将代码从 sql 重写为 redshift