将多行几列变成一行多列(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;
例如,我有一个 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;