有效地将聚合数据连接回原始数据,以便跟踪用于计算聚合的所有原始数据

时间:2017-02-27 20:33:10

标签: sql oracle

我有一些像这样的原始数据:

rawId| Name | Quantity| AggId
-----|------|---------|------
1    | Foo  |    10   | NULL
2    | Foo  |    20   | NULL
3    | Foo  |    30   | NULL
4    | Bar  |    40   | NULL
5    | Bar  |    50   | NULL
6    | Bar  |    60   | NULL

我想聚合它们:

SELECT name, sum(quantity)
FROM foobar
GROUP BY name

并将这些结果存储在以下位置:

AggId| Name | Quantity
-----|------|---------
1    | Foo  |    60
2    | Bar  |    150

我的目标是能够跟踪原始表中的哪些记录用于计算聚合表中的聚合。换句话说,我想将原始表格中AggId的所有foo值更新为1,并将AggId中的所有bar值更新为2原始表格为aggIds

目前,我正在将聚合后的聚合返回到原始分组列,以查找哪个rawIds与哪个SELECT a.aggI r.rawId FROM agg a JOIN raw r ON (a.name = r.name) 相关联:

SELECT rawId, name, quantity, 
    SUM(quantity) OVER (PARTITION BY name) grouped_qty
FROM raw;

有没有更好的方法来实现这一目标?例如,也许通过分析函数?

<supports-screens
    android:resizeable="true"
    android:smallScreens="true"
    android:normalScreens="true"
    android:largeScreens="true"
    android:xlargeScreens="true"
    android:anyDensity="true"/>

结果

rawId| Name | Quantity| grouped_qty
-----|------|---------|------
1    | Foo  |    10   | 60
2    | Foo  |    20   | 60
3    | Foo  |    30   | 60
4    | Bar  |    40   | 60
5    | Bar  |    50   | 60
6    | Bar  |    60   | 60

如果我能够获得分析函数来为聚合集生成序列Id,那将是很好的;但我不确定这是否可行。

2 个答案:

答案 0 :(得分:0)

也许这就是你想要的?

SELECT name, sum(quantity), listagg(foobar.rawid, ',')
FROM foobar
GROUP BY name;

这将包括进入每一行的原始ID列表。请注意,listagg()列的长度限制为4000个字符。

答案 1 :(得分:0)

我相信你想要DENSE_RANK()如果省略分区将使用整个结果集:

SELECT rawId, name, quantity, 
    SUM(quantity) OVER (PARTITION BY name) grouped_qty,
    DENSE_RANK() OVER (ORDER BY name) as name_rank
FROM raw;

更多信息:https://msdn.microsoft.com/en-us/library/ms189798.aspx