如果我有以下两列,我想将记录放入存储桶中,以使总和小于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
答案 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。