如何在Oracle中将表行拆分为固定大小的块

Posted

技术标签:

【中文标题】如何在Oracle中将表行拆分为固定大小的块【英文标题】:How to Split a table rows into fixed size chunk in Oracle 【发布时间】:2020-04-15 12:52:38 【问题描述】:

我有一个超过 100 万行的大表,其中一个数字列作为主键。我正在尝试使用 Oracle sql 查询来获得大小为 500 的拆分。这样我就有了一种存储桶,每个存储桶有 500 条记录,并在该存储桶中给出它们的最大值和最小值。 样本数据

pk_column column1 column2 column3
1002      abcd    1234    15-apr-20
1004      efgh    3435    14-apr-20
1007      ijkl    8855    16-apr-20
....
....
....
2002      asdf    8565    17-apr-20
2005      efgh    5894    14-apr-20   

所需的输出如下所示

bucket_no no_of_element min_value max_value
1         500           1002      2002
2         500           2005      3002
3         500           3003      4002
4         480           4003      4500

我可以使用 NTILE 或 WIDTH_BUCKET 编写的代码无法确定存储桶大小的数量,因此没有任何元素是固定的。随着元素数量不断变化,我无法找到一种方法来动态计算存储桶计数并在 NTILE 或 WIDTH_BUCKET 窗口函数中使用它。以分层方式使用 LEAD 和 LAG 函数非常令人困惑。任何人都可以建议如何解决这个问题。

【问题讨论】:

【参考方案1】:

可以使用解析函数ROW_NUMBER如下:

SELECT
    RN   AS BUCKET_NO,
    COUNT(1) AS NO_OF_ELEMENT,
    MIN(PK_COLUMN) AS MIN_VALUE,
    MAX(PK_COLUMN) AS MAX_VALUE
FROM
    ( SELECT T.*,
            MOD(ROW_NUMBER() OVER(ORDER BY PK_COLUMN) - 1, 500) + 1 RN
        FROM YOUR_TABL T
    )
GROUP BY RN

【讨论】:

PK_COLUMN 没有连续的数字序列,因此使用 MOD 函数将 500 条记录限制到一个存储桶是行不通的。虽然 thr 案例应该适用于连续系列 根据我的测试,500 个结果是桶数说 500 个桶,所以要获得 500 个元素,将行数除以 500 并将其放在 MOD(ROW_NUMBER() OVER (按 PK_COLUMN 排序) - 1, X) + 1 RN

以上是关于如何在Oracle中将表行拆分为固定大小的块的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rust 中将字符串拆分为块以插入空格

将java中的字符串拆分为固定长度的块

java定义固定长度字符串_将java中的字符串拆分为固定长度的块

如何在 Angular 9 中将 HTML 页面拆分为 A4 大小

如何在java中将二维数组拆分为多个不同大小的二维数组

如何在 Python 中将读取一个大的 csv 文件分成大小均匀的块?