将多行(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
(在您的简单情况下,您不需要按任何内容分组。)
我有一个 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
(在您的简单情况下,您不需要按任何内容分组。)