0

我继承了一个迫切需要重构的 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 子句的微小变化 - > 不同的命名列”元素。

我应该把它吸起来并将子查询转储到全局临时表中还是有更好的方法?

4

1 回答 1

1

如果列之间的主要区别是tab2.value2,那么您可以编写一个包含两个阶段的查询:

  1. 用于选择相关数据并将其分组的内部查询tab2.value2

  2. 用于将结果分配给列的外部查询

因此,对于查询的前半部分,它可能如下所示:

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
) 
于 2013-08-21T19:27:12.417 回答