将记录拆分为具有上限和下限的块?
Split records in chunks with upper and lower limit?
我有一个 table (Db2
) 有几百万条记录。过去table中删除了很多记录,因此ROW_NUMBER != PRIMARY KEY。例如如果主键从1开始生成,那么id为1000的记录按主键排序可能是第756条记录。
我有一个需求,需要用下面的方式展示数据。例如
Chunk LowerLimitId UpperLimitId
Chunk1 1 1098 // n = 1000 records between 1 and 1098
Chunk2 1099 2225 // n = 1000 records between 1099 and 2225
Chunk3 2226 3352 // n = 1000 records between 2226 and 3352
等等....
基本上LowerLimit 和Upper Limit 之间的总记录必须是1000。
即
"select count(*) from Table where id between 1 and 1098" = 1000
"select count(*) from Table where id between 1099 and 2225" = 1000
"select count(*) from Table where id between 2226 and 3352" = 1000 and so on
是否有任何 db2 子句或函数可以实现此目的?我不是要完整的查询。只是实现这一目标的方向。
您可以借助 analytic 函数计算行号 row_number
并将数据拆分成块。
示例查询
with t(id) as (
select *
from ( values (1), (3), (5), (6), (20), (13), (25), (23) )
)
, a as (
select
t.id
, trunc((row_number() over(order by id asc) - 1) / 3) as grp
from t
)
select
concat('Chunk', grp + 1) as chunk
, min(id) as LowerLimitId
, max(id) as UpperLimitId
from a
group by grp
CHUNK | LOWERLIMITID | UPPERLIMITID
-----: | -----------: | -----------:
Chunk1 | 1 | 5
Chunk2 | 6 | 20
Chunk3 | 23 | 25
db<>fiddle here
@astentx 的回答已经很好了。我只是对其进行了改进以适应实际需求。
with t(id) as (
select *
from ( values (1), (3), (5), (6), (20), (13), (25), (23) )
)
, a as (
select
t.id,
trunc((row_number() over(order by id asc) - 1) / 3) as grp
from t
)
select
a.grp,
MIN(a.id) as startId,
MAX(a.id) as endId
from a
group by a.grp
您可以使用 Windows 函数来执行此操作。为每一行获取 row_number,然后您将能够 select 块。 select离子可以动态或静态完成。
Row_Number() over order by primaryKeyColumn ....
如果您可以 post 带有数据的 table 脚本,我可以 post 一个完整的答案。
@bluelurker
我有一个 table (Db2
) 有几百万条记录。过去table中删除了很多记录,因此ROW_NUMBER != PRIMARY KEY。例如如果主键从1开始生成,那么id为1000的记录按主键排序可能是第756条记录。
我有一个需求,需要用下面的方式展示数据。例如
Chunk LowerLimitId UpperLimitId
Chunk1 1 1098 // n = 1000 records between 1 and 1098
Chunk2 1099 2225 // n = 1000 records between 1099 and 2225
Chunk3 2226 3352 // n = 1000 records between 2226 and 3352
等等....
基本上LowerLimit 和Upper Limit 之间的总记录必须是1000。
即
"select count(*) from Table where id between 1 and 1098" = 1000
"select count(*) from Table where id between 1099 and 2225" = 1000
"select count(*) from Table where id between 2226 and 3352" = 1000 and so on
是否有任何 db2 子句或函数可以实现此目的?我不是要完整的查询。只是实现这一目标的方向。
您可以借助 analytic 函数计算行号 row_number
并将数据拆分成块。
示例查询
with t(id) as ( select * from ( values (1), (3), (5), (6), (20), (13), (25), (23) ) ) , a as ( select t.id , trunc((row_number() over(order by id asc) - 1) / 3) as grp from t ) select concat('Chunk', grp + 1) as chunk , min(id) as LowerLimitId , max(id) as UpperLimitId from a group by grp
CHUNK | LOWERLIMITID | UPPERLIMITID -----: | -----------: | -----------: Chunk1 | 1 | 5 Chunk2 | 6 | 20 Chunk3 | 23 | 25
db<>fiddle here
@astentx 的回答已经很好了。我只是对其进行了改进以适应实际需求。
with t(id) as (
select *
from ( values (1), (3), (5), (6), (20), (13), (25), (23) )
)
, a as (
select
t.id,
trunc((row_number() over(order by id asc) - 1) / 3) as grp
from t
)
select
a.grp,
MIN(a.id) as startId,
MAX(a.id) as endId
from a
group by a.grp
您可以使用 Windows 函数来执行此操作。为每一行获取 row_number,然后您将能够 select 块。 select离子可以动态或静态完成。
Row_Number() over order by primaryKeyColumn ....
如果您可以 post 带有数据的 table 脚本,我可以 post 一个完整的答案。
@bluelurker