将多行(2 列)转换为一行

Pivot multiple rows (2 columns) into a single row

我有一个 table,它只有两列,第一列是名称标识符,第二列是该标识符的值(基本上 table 作为默认值) , 下面是 table.

的截图

我想要的是将 table 从多行转换为单行,值将是第一列作为列名的列。例如,当前值将转换为以下内容。

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

您可以为此目的使用数据透视子句,如下所示(您的 table 只有 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
    )
)

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

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

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

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

事实上,您可以认为 AGE 存在于四行中的每一行中。当 CODE'AGE' 时,值为 42,当 CODE 为其他值时,值为 NULL。您可以对这四个值使用 SUM()AVG()MIN()MAX()(一个是 42,其余是 NULL);他们都会 return 相同的答案,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

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