不使用Oracle数据库中的临时表或WITH子句重用子查询

asi*_*swt 1 sql oracle

在Oracle 11g中,我有一个表,命名ITEM,其中每个记录被归类到maingroupsubgroup如下:

+-------+---------+----------+
 item_id maingroup subgroup
+-------+---------+---------+
       1 group1    subgroup1
       2 group1    subgroup2
       3 group2    subgroup1
       4 group2    subgroup2
 ...
Run Code Online (Sandbox Code Playgroud)

我必须编写一个程序来报告表中的项目数ITEM.报告输出将类似于:

                 subgroup1   subgroup2   group_total
group1                  10           5            15
group2                   0           1             1
subgroup_total          10           6            16
Run Code Online (Sandbox Code Playgroud)

为此,我将编写一个SQL来查询数据,然后使用Java重新格式化输出.SQL应该自己生成完整的报告,即我将仅使用Java重新格式化输出而不进行任何计算.所以,我决定SQL的输出应该是这样的:

+--------------+-----------+-----+
 maingroup      subgroup    cnt
+--------------+-----------+-----+ 
 group1         subgroup1      10
 group1         subgroup2       5
 group1         group_total    15
 group2         subgroup1       0
 group2         subgroup2       1
 group2         group_total     1
 subgroup_total subgroup1      10
 subgroup_total subgroup2       6
 subgroup_total group_total    16
Run Code Online (Sandbox Code Playgroud)

理想情况下,SQL就像这样简单

select maingroup, subgroup, count(*) cnt from ITEM 
group by maingroup, subgroup union all
select maingroup, 'group_total' as subgroup, count(*) cnt from ITEM
group by maingroup union all
select 'subgroup_total' as maingroup, subgroup, count(*) cnt from ITEM
group by subgroup;
Run Code Online (Sandbox Code Playgroud)

但不,我简化了表格ITEM使问题易于理解,实际上,为了弥补这一点ITEM,我必须使用一个大的子查询,所以它实际上看起来像

select maingroup, subgroup, count(*) cnt from 
       (select maingroup, subgroup from ...) ITEM 
group by maingroup, subgroup union all
select maingroup, 'group_total' as subgroup, count(*) cnt from 
       (select maingroup, subgroup from ...) ITEM 
group by maingroup union all
select 'subgroup_total' as maingroup, subgroup, count(*) cnt from
       (select maingroup, subgroup from ...) ITEM 
group by subgroup;
Run Code Online (Sandbox Code Playgroud)

它使用相同的大子查询3次.我希望我可以重用此子查询,但我没有权限创建表或使用WITH子句.是否可以重新排列上述SQL,以便子查询ITEM只处理一次而不创建临时表或使用WITH子句?

kro*_*lko 5

尝试使用grouping sets子句查询:

SELECT coalesce( maingroup, 'subgroup_total' ) As maingroup,
       coalesce( subgroup, 'group_total' ) As subgroup,
       count(*) cnt 
FROM very_complex_subquery
GROUP BY GROUPING SETS((maingroup, subgroup), (maingroup), (subgroup))
order by 1,2
;
Run Code Online (Sandbox Code Playgroud)

演示:http://sqlfiddle.com/#!4/8ed9b/4