如何基于Oracle中的值总和分配组

时间:2020-07-06 18:26:08

标签: sql oracle group-by

如果我有以下两列,我想将记录放入存储桶中,以使总和小于500。单个输入记录数永远不会大于500。我想在不使用PL / SQL的情况下实现功能

id   | bundle_count                     id   |  bundle_count| group_id
-----|---------                         -----|--------------|--------
1    | 330                              1    | 330          | 1
2    | 150                              2    | 150          | 1
3    | 200          =============>      3    | 200          | 2
4    | 280          Desired output      4    | 280          | 2
5    | 200          =============>      5    | 200          | 3

3 个答案:

答案 0 :(得分:0)

我可以使用以下查询来解决

SELECT id, bundle_count, ceil(sum(bundle_count) over(order by id) /500) as group_id

答案 1 :(得分:0)

免责声明:这不是一个好的答案,因为它在Oracle中不起作用

此解决方案在PostgreSQL中有效,并且不需要ID是连续的。不幸的是,由于Oracle对递归CTE设置了一些限制,因此它在Oracle中不起作用。它不允许在递归CTE的迭代成员中使用LIMIT

我想展示如何在PostgreSQL中完全做到这一点。在这里:

with recursive
x as (
  select id, bundle_count, bundle_count as s, 1 as grp from t where id = 1
 union all (
  select t.id, t.bundle_count, 
    case when x.s + t.bundle_count < 500 then x.s + t.bundle_count
                                         else t.bundle_count end,
    case when x.s + t.bundle_count < 500 then x.grp else x.grp + 1 end
  from t 
  join x on t.id > x.id 
  order by id
  limit 1
  )
)
select * from x order by id

结果:

id  bundle_count    s  grp
--  ------------  ---  ---
 1           330  330    1
 2           150  480    1
 3           200  200    2
 4           280  480    2
 5           200  200    3

请参见DB Fiddle上的运行示例。

答案 2 :(得分:0)

如果ID是连续的,则可以在Oracle中进行操作,如下所示:

with
x (id, bundle_count, s, grp) as (
  select id, bundle_count, bundle_count, 1 from t where id = 1
 union all (
  select t.id, t.bundle_count, 
    case when x.s + t.bundle_count < 500 then x.s + t.bundle_count 
                                         else t.bundle_count end,
    case when x.s + t.bundle_count < 500 then x.grp else x.grp + 1 end
  from t 
  join x on t.id = x.id + 1
  )
)
select * from x order by id;

结果:

id  bundle_count    s  grp
--  ------------  ---  ---
 1           330  330    1
 2           150  480    1
 3           200  200    2
 4           280  480    2
 5           200  200    3

请参见SQL<>Fiddle上的运行示例。

如果它们不是顺序的,则可以使用嵌套的递归CTE。