将多行几列变成一行多列(Oracle 视图)

Making multiple rows with few columns into one row with many columns (Oracle view)

例如,我有一个 table 看起来像:

ID varchar2(6)
ERROR_TYPE varchar2(30)
ERROR_CODE varchar2(6)
ERROR_DESCRIPTION varchar2(50)
REVIEWED_FLAG varchar2(1)

ID 只是典型的随机 ID,ERROR_TYPE 是导致错误的功能,比如订单或发货。 REVIEWED_FLAG 是 'Y' 或 'N',ERROR_DESCRIPTION 几乎就是这样,ERROR_CODE 是一个代码,例如 1A 或 2B,其中:
0 - passed/there 没有错误,或者
1 - failed/there 是一个错误
完整的错误代码看起来像 1A=0 或 2B=1(不是我的选择,这是我要处理的)。

一个标准

select ID, ERROR_CODE from ERROR_TABLE where ERROR_TYPE = 'SHIPMENT'

将 return 结果集如下:

ID      ERROR_CODE  ERROR_TYPE
100001  1A=0        SHIPMENT
100001  2B=1        SHIPMENT
100001  3A=1        SHIPMENT
100001  4B=0        SHIPMENT
100002  1A=1        SHIPMENT
100002  2B=1        SHIPMENT
100002  3A=0        SHIPMENT
100002  4B=0        SHIPMENT

用户想看的是:

ID       ERROR_TYPE  ERROR_CODE_1A  ERROR_CODE_2B  ERROR_CODE_3A  ERROR_CODE_4B
1000001  SHIPMENT          0              1              1              0
1000002  SHIPMENT          1              1              0              0

我对 PIVOT 的了解是它只适用于聚合函数。这不是连接,因为值在它们自己的列中。

我最终创建的视图基本上是

create view V_SHIPMENT_ERRORS as
with ERROR1A as (select ID, substr(ERROR_CODE, 4) as ERROR_CODE_1A from error_table 
                  where error_type = 'SHIPMENT' and error_code like '1A%'),
with ERROR2B as (select ID, substr(ERROR_CODE, 4) as ERROR_CODE_2B from error_table 
                  where error_type = 'SHIPMENT' and error_code like '2B%'),
with ERROR3A as (select ID, substr(ERROR_CODE, 4) as ERROR_CODE_3A from error_table 
                  where error_type = 'SHIPMENT' and error_code like '3A%'),
with ERROR4B as (select ID, substr(ERROR_CODE, 4) as ERROR_CODE_4B from error_table 
                  where error_type = 'SHIPMENT' and error_code like '4B%')
select a.ID, error_code_1A, error_code_2B, error_code_3A, error_code_4B
  from error1a a, error2b b, error3a c, error4b d
 where a.id = b.id
   and a.id = c.id
   and a.id = d.id;

这确实给了我想要的结果集。

基本问题 - 是否有更有效的方法来仅使用 SQL 进行这样的 row/column 操作?

对此的评论是,如果有人想做同样的事情,我希望我所做的工作至少能帮助他们。我在任何地方都找不到这种类型的解决方案,它是多个站点上的想法的组合导致的。

您可以使用条件聚合:

select id, shipment_type,
       max(case when error_code like '1A=' then substr(error_code, -1) end) as ec_1a,
       max(case when error_code like '2B=' then substr(error_code, -1) end) as ec_2b,
       max(case when error_code like '3A=' then substr(error_code, -1) end) as ec_3a,
       . . .
from error_table
group by id, shipment_type;