【问题标题】:Is it possible to get partitioned data using SQL?是否可以使用 SQL 获取分区数据?
【发布时间】:2016-10-14 09:56:01
【问题描述】:

我有一个 RDBMS 表,其列 BIGINT 类型和值不是连续的。我有一个 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 子句中传递上述值范围,以获取每个线程的划分数据。

目前,我可以通过 Java 进行此分区,方法是将所有值放入 List(在从 DB 获取所有值之后),然后在这些特定索引处获取值 - {0,PARTITION_SIZE},{PARTITION_SIZE+1,2*PARTITION_SIZE} ..etc 但存在问题List 可能有数百万条记录,不建议存储在内存中。

所以我想知道是否可以使用 SQL 本身编写这样的查询,它会返回如下的范围?

row-1 -> minId , maxId

row-2 -> minId , maxId

....

数据库是 DB2。

例如,

对于表列值 1,2,12,3,4,5,20,30,7,9,11partition size =2 的 SQL 查询结果应该是 {1,2},{3,4} ,{5,7},{9,11},{12,20},{30}

【问题讨论】:

  • 您的问题是否正确 - 您想使用多个线程从 DB2 中并行检索数据。你问如何选择行来获得不相交的 SELECT?
  • 感谢您的调查。我在问题中添加了一个示例,是的,我认为您理解正确。
  • 我添加的示例对于最后一组只有一个值,我将在程序中处理这种情况,因为没有最终值。

标签: java sql db2


【解决方案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。

【讨论】:

  • 所以基本上用上面的查询,如果我的表只有一列 -ÌDof type BIGINT ,我会得到表 numbered_rows_temp 中分区范围的最终值,我可以使用 @987654325 @ 对于我线程的 SELECT sql 中来自 numbered_rows_temp 表的每个 ID?我的意思是,我必须为每个范围分别计算起始索引,但这没关系。
  • 不 - 忘记范围 - 在这种情况下 mod (modulo) 会进行计算,在你有两个分区的情况下,每个奇数行将在分区 1 中,每个偶数行将在分区 2 中。
  • 如果我将第一个查询作为内部查询而不是临时表传递,我没有得到准确的结果,但如果我不单独执行 ORDER BY col1,它可以正常工作,我执行 over (ORDER BY col1)
【解决方案2】:

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)

【讨论】:

  • 谢谢,您的解决方案也可以工作,并在同一行提供范围值。
猜你喜欢
  • 2017-05-05
  • 1970-01-01
  • 1970-01-01
  • 2022-06-23
  • 1970-01-01
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多