【问题标题】:Oracle Get sum of distinct group without subqueryOracle获取不带子查询的不同组的总和
【发布时间】:2015-07-21 23:43:17
【问题描述】:

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

所以这是我(已经)工作的例子:

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 子句显示了一个包含数据的简化表格。现在的问题是最后一列是子组的预算。结果我需要主组的预算。这意味着我必须对主组中的所有值求和,但前提是子组不同(这里我需要某种不同的值)。

不幸的是一个简单的

sum(distinct subgroupbudget) over(partition by maingroup)

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

【问题讨论】:

  • 感谢您提供示例数据,我们通常看不到。为此+1。您能否也添加您想要的输出?
  • 如果 'random' 和 'random1' 的 subgroupbudget 不同,Group1 的总和是多少?
  • 您好,感谢您的回答。输出已经是我想要的,但 SQL 不是。正如我所说,我不喜欢子查询,我想也许有更好的方法可以在没有子查询的情况下解决这个问题。
  • @Boneist:random 和 random2 的预算不能不同,因为 subgroupbudget 指的是列子组(均为 'Name 1')
  • 您的意思是在您的实际查询中,您是从基于子组的其他表中获取的,因此这些值仅在您的最终查询中重复?或者您是说您的数据模型没有标准化,并且您正在复制信息?因为如果是后者,您如何保证各行的值没有不同?如果是前者,您可能会在使用随机值填充行之前重写查询以求和。

标签: sql oracle group-by sum partition


【解决方案1】:

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

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

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

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

【讨论】:

  • 嗨 Boneist,非常有趣!我不这么认为,但是根据行号为每个子组仅设置一次(子组)预算几乎是天才,并且是我的问题的完美“解决方案”。非常感谢!
猜你喜欢
  • 2013-12-30
  • 1970-01-01
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 2017-07-14
相关资源
最近更新 更多