Oracle在没有子查询的情况下获取不同组的总和
Oracle Get sum of distinct group without subquery
我已经有了一个工作示例,它完全符合我的需要。
现在的问题是,我不是子查询的忠实粉丝,我认为这个问题可能有更好的解决方案。
所以这是我的(已经)工作示例:
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
如您所见,with 子句显示了一个简化的 table 数据。现在的问题是最后一列是子组的预算。结果我需要主要集团的预算。这意味着我必须对主组内的所有值求和,但前提是子组不同(这里我需要某种不同)。
可惜简单
sum(distinct subgroupbudget) over(partition by maingroup)
不会起作用,因为数字(子组预算)可以相同(如示例中所示)
假设对于 maingroup/subgroup,子组预算始终相同(或者您只为子组取最高值),这应该可行:
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
这实际上是说,对于 maingroup/subgroup,您只想在总和中使用该子组中行的值之一(最高)。
它是否比您的原始查询 "better"(即性能更高)是您必须测试的。子查询不一定是坏事;它们是一种工具,有时它们是正确的工具。
我已经有了一个工作示例,它完全符合我的需要。 现在的问题是,我不是子查询的忠实粉丝,我认为这个问题可能有更好的解决方案。
所以这是我的(已经)工作示例:
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
如您所见,with 子句显示了一个简化的 table 数据。现在的问题是最后一列是子组的预算。结果我需要主要集团的预算。这意味着我必须对主组内的所有值求和,但前提是子组不同(这里我需要某种不同)。
可惜简单
sum(distinct subgroupbudget) over(partition by maingroup)
不会起作用,因为数字(子组预算)可以相同(如示例中所示)
假设对于 maingroup/subgroup,子组预算始终相同(或者您只为子组取最高值),这应该可行:
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
这实际上是说,对于 maingroup/subgroup,您只想在总和中使用该子组中行的值之一(最高)。
它是否比您的原始查询 "better"(即性能更高)是您必须测试的。子查询不一定是坏事;它们是一种工具,有时它们是正确的工具。