我使用以下查询从3个表中获取数据,SOURCE1,SOURCE2,SOURCE3需要插入到另一个表FINAL中。我想知道下面的查询是否可以进一步调整。
SELECT s3.unit ,s2.col1,s2.col2, '00-1' dest
FROM source1 s1
INNER JOIN source2 s2 ON s1.altunit = s2.unit
INNER JOIN source3 s3 ON s1.unit = s3.unit
WHERE sysdate BETWEEN s1.e_date AND s1.d_date
AND s1.unit IN (SELECT unit FROM source1 WHERE u_sw = 1)
UNION
SELECT s3.price,s2.col1,s2.col2, '00-1' dest
FROM source1 s1
INNER JOIN source2 s2 ON s1.altunit = s2.unit
INNER JOIN source3 s3 ON s1.unit = s3.unit
WHERE sysdate BETWEEN s1.e_date AND s1.d_date
AND s1.unit IN (SELECT unit FROM source1 WHERE u_sw = 1)
UNION
SELECT s3.price,s2.col1,s2.col2, s2.dest
FROM source1 s1
INNER JOIN source2 s2 ON s1.altunit = s2.unit
INNER JOIN source3 s3 ON s1.unit = s3.unit
WHERE sysdate BETWEEN s1.e_date AND s1.d_date
AND s1.unit IN (SELECT unit FROM source1 WHERE u_sw = 1)
UNION
SELECT s3.cost,s2.col1,s2.col2, s2.dest
FROM source1 s1
INNER JOIN source2 s2 ON s1.altunit = s2.unit
INNER JOIN source3 s3 ON s1.unit = s3.unit
WHERE sysdate BETWEEN s1.e_date AND s1.d_date
AND s1.unit IN (SELECT unit FROM source1 WHERE u_sw = 1)
答案 0 :(得分:0)
只有SELECT语句第1位的数据有所不同。剩余条件 - JOIN和WHERE子句保持不变。我们只需要为我们选择的每一行发出4行:
SELECT variants.*
FROM source1 s1
INNER JOIN source2 s2 ON s1.altunit = s2.unit
INNER JOIN source3 s3 ON s1.unit = s3.unit
CROSS APPLY (
SELECT s3.unit ,s2.col1,s2.col2, '00-1' dest UNION
SELECT s3.price,s2.col1,s2.col2, '00-1' dest UNION
SELECT s3.price,s2.col1,s2.col2, s2.dest UNION
SELECT s3.cost,s2.col1,s2.col2, s2.dest
) variants
WHERE sysdate BETWEEN s1.e_date AND s1.d_date
AND s1.unit IN (SELECT unit FROM source1 WHERE u_sw = 1)
答案 1 :(得分:0)
with tmp (unit, price, cost, col1, col2, dest1, dest2) as (
SELECT s3.unit, s3.price, s3.cost, s2.col1, s2.col2, s2.dest, '00-1'
FROM source1 s1
JOIN source2 s2
ON s1.altunit = s2.unit
JOIN source3 s3
ON s1.unit = s3.unit
WHERE sysdate BETWEEN s1.e_date AND s1.d_date
AND s1.unit IN (SELECT unit FROM source1 WHERE u_sw = 1)
)
select unit, col1, col2, dest2 from tmp
union
select price, col1, col2, dest2 from tmp
union
select price, col1, col2, dest1 from tmp
union
select cost, col1, col2, dest1 from tmp
我认为Oracle会以比原始查询更有效的方式对其进行评估。
答案 2 :(得分:0)
如果我正确读取这个,除了select
之外,所有四个子查询都是相同的。通常,最快的方法是使用cross join
和条件逻辑
SELECT (case when n.n = 1 then s3.unit
when n.n in (2, 3) then s3.price
when n.n = 4 then s3.cost
end) as unit,
s2.col1, s2.col2,
(case when n.n in (1, 2) then '00-1'
when n.n in (3, 4) then s2.dest
end) as dest
FROM source1 s1 INNER JOIN
source2 s2
ON s1.altunit = s2.unit INNER JOIN
source3 s3
ON s1.unit = s3.unit CROSS JOIN
(select 1 as n from dual union all select 2 from dual union all select 3 from dual union all select 4 from dual
) n
WHERE sysdate BETWEEN s1.e_date AND s1.d_date
AND s1.unit IN (SELECT unit FROM source1 WHERE u_sw = 1);
如果您仍需要消除重复项,请使用select distinct
。
答案 3 :(得分:0)
CROSS APPLY
是这样做的方式,正如 @usr 建议的那样。
我只想补充说AND s1.unit IN (SELECT unit FROM source1 WHERE u_sw = 1)
可以成为一个性能杀手。
这取决于你可以拥有多少个不同的“单位”:
SELECT unit FROM source1 WHERE u_sw = 1
返回4个值,请保持这样。INNER JOIN
代替:原文:
FROM source1 s1
[...]
WHERE
s1.unit IN (SELECT unit FROM source1 WHERE u_sw = 1)
致:
FROM source1 s1
INNER JOIN source1 s1limit
ON s1limit.unit = s1.unit
AND s1limit.u_sw = 1