Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在oracle中基于值之和分配组_Sql_Oracle_Group By - Fatal编程技术网

Sql 如何在oracle中基于值之和分配组

Sql 如何在oracle中基于值之和分配组,sql,oracle,group-by,Sql,Oracle,Group By,若我有两列,如下所示,我希望将记录放入桶中,使总和小于500。单个输入记录计数永远不会超过500。我想通过使用PL/SQL函数来实现 id | bundle_count id | bundle_count| group_id -----|--------- -----|--------------|-------- 1 | 330 1

若我有两列,如下所示,我希望将记录放入桶中,使总和小于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

我可以用下面的查询来解决这个问题

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

我可以用下面的查询来解决这个问题

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

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

此解决方案在PostgreSQL中工作,不要求
ID
s是连续的。不幸的是,它在Oracle中不起作用,因为Oracle对递归CTE有一些限制;它不允许在递归CTE的迭代成员中限制

我想展示一下如何在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

请参见运行示例。

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

此解决方案在PostgreSQL中工作,不要求
ID
s是连续的。不幸的是,它在Oracle中不起作用,因为Oracle对递归CTE有一些限制;它不允许在递归CTE的迭代成员中限制

我想展示一下如何在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
s是连续的,则可以在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;
请参阅上的运行示例


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

如果
ID
s是顺序的,则可以在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;
请参阅上的运行示例


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

是否应该对ID进行排序?您使用的是什么版本的Oracle?@GordonLinoff-ID的顺序并不重要。只需要分配到不同的存储桶。我正在使用Oracle 18c。这使得这成为一个很难实现的装箱问题。如果有一行id为6且捆绑数量为15,该怎么办?既然该组中还有15人的空间,那么是否应该将其添加到
组id
=1中?或者应该将其添加到
组\u id
=3中,因为我们正在按顺序处理行?@matthewmpeak-可以添加到任何存储桶中,如果总和低于500,则需要将其放入不同的存储桶中。应该订购id吗?您使用的是什么版本的Oracle?@GordonLinoff-ID的顺序并不重要。只需要分配到不同的存储桶。我正在使用Oracle 18c。这使得这成为一个很难实现的装箱问题。如果有一行id为6且捆绑数量为15,该怎么办?既然该组中还有15人的空间,那么是否应该将其添加到
组id
=1中?或者应该将其添加到
组\u id
=3,因为我们正在按顺序处理行?@matthewmpeak-可以添加到任何存储桶中,只要总和小于500,就需要将其放入不同的存储桶中。