Oracle 无需子查询即可获取不同组的总和

use*_*355 5 sql oracle group-by sum partition

我已经有一个工作示例,它完全满足我的需要。现在的问题是,我并不是真正喜欢子查询,我认为可能有更好的解决方案来解决这个问题。

这是我的(已经)工作示例:

with t as
(
select  'Group1' as maingroup,'Name 1' as subgroup, 'random' as random, 500 as subgroupbudget from dual
union all
select 'Group1','Name 1','random2',500 from dual
union all
select 'Group1','Name 2','random3', 500 from dual
union all
select 'Group2','Name 3','random4', 500 from dual
union all
select 'Group2','Name 4','random5',500 from dual
union all
select 'Group2','Name 5', 'random6',500 from dual
)
select
maingroup,
subgroup,
random,
(select distinct sum(subgroupbudget) over(partition by maingroup) from t b where a.maingroup=b.maingroup group by maingroup,subgroup,subgroupbudget) groupbudget
from t a
group by  maingroup, subgroup ,subgroupbudget, random
order by maingroup, subgroup
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,with 子句显示了带有数据的简化表。现在的问题是最后一列是子组的预算。结果我需要主组的预算。这意味着我必须对主组内的所有值求和,但前提是子组不同(这里我需要某种不同的值)。

不幸的是一个简单的

sum(distinct subgroupbudget) over(partition by maingroup)
Run Code Online (Sandbox Code Playgroud)

不起作用,因为数字(子组预算)可以相同(如示例中所示)

Bon*_*ist 3

假设对于主组/子组,子组预算始终相同(或者您只取子组的最高值),这应该有效:

with t as (select  'Group1' as maingroup,'Name 1' as subgroup, 'random' as random, 500 as subgroupbudget from dual
           union all
           select 'Group1','Name 1','random2',500 from dual
           union all
           select 'Group1','Name 2','random3', 500 from dual
           union all
           select 'Group2','Name 3','random4', 500 from dual
           union all
           select 'Group2','Name 4','random5',500 from dual
           union all
           select 'Group2','Name 5', 'random6',500 from dual),
    t1 as (select maingroup,
                  subgroup,
                  random,
                  case when row_number() over (partition by maingroup, subgroup order by subgroupbudget desc) = 1 then subgroupbudget
                  end subgroupbudget
           from t)
select maingroup,
       subgroup,
       random,
       sum(subgroupbudget) over (partition by maingroup) groupbudget
from   t1;

MAINGROUP SUBGROUP RANDOM  GROUPBUDGET
--------- -------- ------- -----------
Group1    Name 1   random         1000
Group1    Name 1   random2        1000
Group1    Name 2   random3        1000
Group2    Name 3   random4        1500
Group2    Name 4   random5        1500
Group2    Name 5   random6        1500
Run Code Online (Sandbox Code Playgroud)

这实际上是说,对于主组/子组,您只想在总和中使用该子组中的行的值之一(最高)。

您必须测试它是否比原始查询“更好”(即性能更高)。子查询不一定是坏事;它们是一种工具,有时它们是正确使用的工具。