【问题标题】:Pivot multiple rows (2 columns) into a single row将多行(2 列)旋转为单行
【发布时间】:2022-01-20 12:04:35
【问题描述】:

我有一个表,它只有 2 列,第一列是名称标识符,第二列是此标识符的值(基本上该表充当默认值),下面是该表的屏幕截图。

我想要的是将表格从多行转换为单行,并且值将是第一列作为列名的列。例如,将当前值转换为下面的值。

我阅读了 PIVOT 运算符,但是它需要在 pivot 子句中使用聚合函数,但我认为在这种情况下我不能使用聚合函数,它只是将行值设置为列值。 PIVOT 是否可以实现这一点,还是我应该使用其他构造来实现这一点?

【问题讨论】:

  • "...但我认为我不能使用聚合函数..." -- 这取决于真实数据的质量。您希望查询做什么,例如,如果数据包含两行 AGE 的不同值(例如 4255)?

标签: sql oracle oracle11g


【解决方案1】:

已经有一个正确的技术答案,显示了如何在您的情况下进行调整。

让我解释一下为什么这种“转轴”在逻辑层面上确实是一种聚合。

您有一组四行,并且您想为该组生成一个“摘要行”。 (想象一下,并行地,您有几个员工由员工 ID 标识,在一个附加列中;每个员工最多有四行,用于相同的属性。然后您按员工 ID 分组,每个组最多有四行 -如果缺少属性,则更少 - 并且您希望为每个组获取一个“摘要行”。)

这是一种聚合形式。但是对于什么聚合函数? AGE 似乎只有一个值,STATUS 的值只有一个,等等。

事实上,您可以认为AGE 存在于四行中的每一行中。当CODE'AGE' 时,值为42,当CODE 为其他值时,值为NULL。您可以在这四个值上使用SUM()AVG()MIN()MAX()(一个是42,其余是NULL);他们都会返回相同的答案,42 - 因为所有聚合函数都会忽略 NULL

如果值是字符串而不是数字怎么办?答:同样的事情——除了你不能使用SUM()AVG()。你还有MIN()MAX()。事实上,你也可以使用其他聚合函数——它们只需要是字符串聚合。例如,您可以使用LISTAGG()。同样,您正在聚合一个非NULL 字符串,其他的是NULL,因此结果将只是一个非NULL 字符串。

在 Oracle 在 11.1 版本的数据库中引入 PIVOT 运算符之前,程序员已经能够进行透视 - 就像我解释的那样使用条件聚合。类似的东西

select max(case when code = 'AGE' then AGE end) as AGE,
       ...
from   ...
group  by EMPLOYEE_ID   -- in the more general case

(在您的简单情况下,您不需要按任何内容分组。)

【讨论】:

  • 感谢 mathguy 的解释,我现在知道它是如何与 max 函数和字符串值一起工作的。
【解决方案2】:

您可以为此目的使用 pivot 子句,如下所示(您的表只有 2 列,我假设您没有任何重复的代码)

select *
from Yourtable
pivot (
max(value) for code in (
        'AGE' as AGE
    ,   'FIRST_NAME' as FIRST_NAME
    ,   'LAST_NAME' as LAST_NAME
    ,   'STATUS' as STATUS
    )
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多