我有一个列BIGINT
类型的RDBMS表,值不是连续的。我有一个java程序,我希望每个线程按PARTITION_SIZE
获取数据,即我想要一对列值,例如在结果上执行ORDER BY
之后,
Column_Value at Row 0 , Column_Value at Row `PARTITION_SIZE`
Column_Value at Row `PARTITION_SIZE+1` , Column_Value at Row `2*PARTITION_SIZE`
Column_Value at Row `2*PARTITION_SIZE+1` , Column_Value at Row `3*PARTITION_SIZE`
最后,我将在SELECT查询的BETWEEN
子句中传递上述值范围,以获取每个线程的分割数据。
目前,我可以通过将所有值放在List
中(在从DB获取所有值之后),然后获取这些特定索引的值 - {0,PARTITION_SIZE},{PARTITION_SIZE+1,2*PARTITION_SIZE}
..来通过Java进行此分区。但问题是List
可能有数百万条记录,不建议存储在内存中。
所以我想知道是否有可能使用SQL本身编写这样的查询,这会返回如下所示的范围?
row-1 - > minId,maxId
第2行 - > minId,maxId
...
数据库是DB2。
例如,
对于表列值1,2,12,3,4,5,20,30,7,9,11
,分区大小= 2 的SQL查询结果应为{1,2},{3,4} ,{5,7},{9,11},{12,20},{30}
。
答案 0 :(得分:1)
在我看来,mod()函数可以解决您的问题,您可以选择动态数量的分区。
WITH numbered_rows_temp as (
SELECT rownumber() over () as rownum,
col1,
...
coln
FROM table
ORDER BY col1)
SELECT * FROM numbered_rows_temp
WHERE mod(rownum, <numberofpartitions>) = 0
填写相应内容并在查询中将结果从0更改为-1。
答案 1 :(得分:1)
Michael Tiefenbacher's answer可能更有用,因为它可以避免额外的查询,但如果您确实想要确定ID范围,这可能对您有用:
WITH parms(partition_size) AS (VALUES 1000) -- or whatever
SELECT
MIN(id), MAX(id),
INT(rn / parms.partition_size) partition_num
FROM (
SELECT id, ROW_NUMBER() OVER (ORDER BY id) rn
FROM yourtable
) t , parms
GROUP BY INT(rn / parms.partition_size)