Oracle - 按多维数据集分组 - 按不同列求和
Posted
技术标签:
【中文标题】Oracle - 按多维数据集分组 - 按不同列求和【英文标题】:Oracle - Group by Cube - Sum by distinct column 【发布时间】:2015-04-14 12:25:52 【问题描述】:样本数据:
product_type |segment_type |promotion_id |promotion_value
-----------------------------------------------------------
Beer |Regional |1 |20
Beer |National |1 |20
Beer |Regional |2 |20
Beer |National |2 |20
Beer |National |3 |30
Beer |Regional |4 |40
Soda |Regional |5 |50
Soda |National |5 |50
Soda |Regional |6 |50
Soda |National |6 |50
Soda |National |7 |15
Soda |Regional |8 |20
目标:考虑不同的促销活动,获得按 product_type 和 segment_type(立方体)分组的总促销价值。请注意,一次促销可以覆盖一个或两个细分市场(区域和国家)。
期望的结果:
product_type |segment_type |promotion_value
-------------------------------------------------
Beer | |110
Beer |Regional |80
Beer |National |70
Soda | |135
Soda |Regional |120
Soda |National |115
我目前的SQL如下:
SELECT product_Type,
segment_type,
sum(promotion_value)promotion_value
from sample_data
group by product_type,
cube(segment_type)
目前的结果是:
product_type |segment_type |promotion_value
-------------------------------------------------
Beer | |150
Beer |Regional |80
Beer |National |70
Soda | |235
Soda |Regional |120
Soda |National |115
SQLFiddle:link
有没有办法达到预期的效果?
【问题讨论】:
区域和国家不应该加起来有什么具体原因吗? @mucio:一次促销可以同时到达区域和国家细分市场,目标是通过不同的促销获得促销价值。 【参考方案1】:使用Sum(Distinct..)
获取组中唯一值的总和
SELECT product_Type,
segment_type,
sum(distinct promotion_value)promotion_value
from sample_data
group by product_type,
cube(segment_type)
order by product_type
SQLFIDDLE DEMO
更新:
SELECT product_Type,
segment_type,
Sum(DISTINCT promotion_value)
FROM (SELECT product_Type,
segment_type,
Sum(promotion_value) promotion_value
FROM sample_data
GROUP BY product_type,
segment_type) a
GROUP BY product_type,
cube( segment_type )
SQLFIDDLE DEMO
【讨论】:
这将如何与具有相同价值的不同促销活动一起使用? @Mt.Schneiders - 在群组中添加promotion_id
在组中添加promotion_id 将使其重复每个促销的总数:sqlfiddle.com/#!4/f47b3/1
@Mt.Schneiders - 这种情况下的预期输出是什么
如果所有促销活动都适用于“国家”和“区域”细分市场,那么您的解决方案有效,在我的情况下,这不是 100% 正确的。我会用这个新的上下文更新问题。【参考方案2】:
编辑:
我真的很喜欢您使用cube
的想法,以前从未使用过它,而且我认为如果您正在处理适当的维度结构化表格,这非常酷。
很遗憾,这不是您的情况。 Cube 将尝试生成可能的总计和小计,但理解它不应该添加您的一些数据并不是那么聪明。
segment_type
和promotion_id
似乎是多对多关系,这通常不是问题,但不能通过cube
扩展自动处理。
所以最后,为了安全起见,我认为最好的解决方案是创建两个查询来正确聚合您的数据:
select product_Type,
segment_type,
sum(promotion_value) promotion_value
from sample_data
group by product_type,
segment_type
union all
select product_Type,
null,
sum(promotion_value) promotion_value
from (
select distinct product_Type,
promotion_id,
promotion_value
from sample_data
)
group by product_type
order by product_type
Demo in SQLFiddle.
【讨论】:
我更新了我的问题以更好地解释所需的结果。你的支票你能回答吗? 我认为它不适用于新的示例数据:sqlfiddle.com/#!4/d5663/2 我做了一些其他测试,我认为这不适用于cube
。检查我的更新答案
感谢您的回答。关于数据的结构,我的示例数据不是来自单个表,它实际上是来自多个表的视图。此外,这是一个简化的案例,因为我在现实中还有更多维度。如果我要使用您的解决方案,我会在每个维度有一个联合,对吗?
我会说每个级别的聚合【参考方案3】:
选择product_type,''作为segment_type,sum(promotion_value)作为promotion_value 来自 stack_sam 按产品类型分组 联盟 选择 product_type,segment_type,sum(promotion_value) 来自 stack_sam 按产品类型、细分类型分组 按 1 排序;
【讨论】:
以上是关于Oracle - 按多维数据集分组 - 按不同列求和的主要内容,如果未能解决你的问题,请参考以下文章