将 SQL 结果拆分为最大大小 = n 的组

Mic*_*cht 4 sql postgresql plpgsql

我有一张桌子

 id | volume_id| ... |
----+----------+-----+
  1 |       1  | ... |
  2 |       2  | ... |
  3 |       1  | ... |
  4 |       3  | ... |
  5 |       2  | ... |
  ...
Run Code Online (Sandbox Code Playgroud)

我可以做一个简单的分组查询:

select volume_id, count(*), min(id) as min_id, max(id) as max_id
from my_table
group by volume_id;
Run Code Online (Sandbox Code Playgroud)

这将产生结果:

 volume_id | count | min_id | max_id    
-----------+-------+--------+--------
         1 | 67330 |  ...   | ...
         2 | 67330 |  ...   | ...
         3 | 67330 |  ...   | ...
         4 | 67330 |  ...   | ...
Run Code Online (Sandbox Code Playgroud)

但我想将结果分成 40K 行的组。所以结果应该是这样的:

 volume_id | count | min_id | max_id    
-----------+-------+--------+--------
         1 | 40000 |  ...   | ...      <- first  group of IDs for volume 1
         1 | 27330 |  ...   | ...      <- second group of IDs for volume 1
         2 | 40000 |  ...   | ...
         2 | 27330 |  ...   | ...
         3 | 40000 |  ...   | ...
         4 | 27330 |  ...   | ...
Run Code Online (Sandbox Code Playgroud)

ID 应该被拆分,max_id以便第一组的ID 应该小于min_id第二组的ID ,依此类推。

如果有人知道如何编写这样的查询(或 plsql 函数,如果没有其他方法),我将不胜感激。

我正在使用 Postgresql 9.5。

Gor*_*off 7

您可以使用rank()(或者row_number()如果没有重复项)来枚举组。然后在 中进行简单的算术运算group by

select volume_id, count(*), min(id) as min_id, max(id) as max_id
from (select t.*,
             rank() over (partition by volume_id order by id) as seqnum
      from my_table t
     ) t
group by volume_id, floor((seqnum - 1) / 40000)
order by volume_id, min(id);
Run Code Online (Sandbox Code Playgroud)