[英]Oracle 12c - Creating two records out of 1 record in an insert select
我有一个插入选择查询,它带回大约 100 万条记录,每条记录大约有 30 列,有两列(性能总计,机械总计)。 其中一列将有一个值。 Performance Total 可能有 nulll 值,mechanical total 可能有 null 值,或者两者都有该记录的值。
当记录在两列(性能总计、机械总计)中都有值时,我希望 SQL 查询创建两条记录,因此将两条记录插入到一个表中而不是一个。 一项记录是性能记录,一项记录是机械记录。 性能总计或机械总计将插入到有总计字段的表中。
如何在不创建 UNION 语句的情况下在 SQL 查询中完成此操作,因为它会导致性能问题?
我不认为这比使用 UNION 更有效率,但你可以这样做:
insert into target (a, b, c, rec_type, rec_total)
select mt.a, mt.b, mt.c,
case when r.rec = 1 then 'PERFORMANCE' else 'MECHANICAL' end
case when r.rec = 1 then mt.perf_total else mt.mech_total end
from mytable mt
cross join (select rownum rec from dual connect by level <= 2) r
where (mt.perf_total is not null and r.rec=1)
or (mt.mech_total is not null and r.rec = 2);
您正在描述union all
:
select . . . , 'performance' as which, performance_total
from t
where performance_total is not null
union all
select . . . , 'mechanical' as which, mechanical_total
from t
where mechanical_total is not null;
这确实需要扫描表两次。 我不确定这对具有一百万行的基表是否如此重要,它应该适合内存。
如果是这样(如果表真的是一个视图,则尤其如此),那么我会将逆枢轴表述为:
select . . . , pm.which,
(case when which = 'performance' then performance_total
else mechanical_total
end)
from t cross join
(select 'performance' as which from dual union all
select 'mechanical' as which from dual
) pm
where (case when which = 'performance' then performance_total
else mechanical_total
end) is not null;
或者,在最新版本的 Oracle 中,使用横向连接:
select . . . , pm.which, pm.total
from t cross join lateral
(select 'performance' as which, performance_total as total from dual union all
select 'mechanical' as which, mechanical_total from dual
) pm
where total is not null;
只是为了让您知道我在我的唱片中使用了 UNPIVOT,它最终奏效了。
SELECT TYPE_OF_RECORD, RECORD_POINTS, 28 columns
FROM ( SELECT PERF_TOTAL, MECH_TOTAL, 28 columns
FROM TABLE UNPIVOT (RECORD_POINTS FOR TYPE_OF_RECORD IN
(PERF_TOTAL AS 'PERF',
MECH_TOTAL AS 'MECH'))
WHERE RECORD_POINTS > 0
) X;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.