我继承了一个迫切需要重构的SQL查询。查询(6页长)看起来像这样:
SELECT (count(*) from tab1, tab2, tab3 where tab1.value1 is not null
and tab2.tab3id = tab3.id and tab3.value4 in (1,2,3) and tab3.value3 = 15 and tab2.value2 = 10 [...]) as RESULT1,
SELECT (sum(tab3.value5) from [EXACT SAME QUERY AS ABOVE]) AS RESULT1_SUM
SELECT (count(*) from tab1, tab2, tab3 where tab1.value1 is not null
and tab2.tab3id = tab3.id and tab3.value4 in (1,2,3) and tab3.value3 = 15 and tab2.value2 = 27 [...]) as RESULT2,
...[AD NAUSEAM for several more columns]
UNION
SELECT [same as first query, but now tab1.value1 is NULL]
...[now sum()]
FROM DUAL [of course!]
这个混乱的最终结果是一个2行/ 16列结果,其中行的不同是tab1.value1在(主要是复制和粘贴)子查询中是否为空,并且列的不同之处在于子查询的WHERE子句的其他值。
RESULT1 RESULT1_SUM RESULT2 RESULT2_SUM ...
IS_NOT_NULL 300 120000 90 80000
IS_NULL 70 90000 54 95000
我必须复制同样的输出。我的第一直觉是将子查询的公共元素拉出到WITH子句中。但我仍然坚持如何在不使用每列的单独子查询的情况下获得“WHERE子句的小变化 - >不同命名列”元素的复制。
我应该把它搞砸并将子查询转储到全局临时表中还是有更好的方法?
答案 0 :(得分:1)
如果列之间的主要差异为tab2.value2
,那么您可以编写一个包含两个阶段的查询:
内部查询,用于选择相关数据并按tab2.value2
分组
将结果分配给列的外部查询
因此,对于查询的前半部分,它可能如下所示:
select
sum(case when val = 10 then cnt end) as RESULT1,
sum(case when val = 10 then sm end) as RESULT1_SUM,
sum(case when val = 15 then cnt end) as RESULT2,
sum(case when val = 15 then sm end) as RESULT2_SUM,
...
from (
select tab2.value2 as val, count(*) as cnt, sum(tab3.value5) as sm
from tab1, tab2, tab3
where tab1.value1 is not null
and tab2.tab3id = tab3.id
and tab3.value4 in (1,2,3)
and tab3.value3 = 15
group by tab2.value2
)