【问题标题】:Apply OFFSET and LIMIT in ORACLE for complex Join Queries?在 ORACLE 中应用 OFFSET 和 LIMIT 来处理复杂的联接查询?
【发布时间】:2020-10-11 09:47:40
【问题描述】:

我正在使用Oracle 11g 并且有一个复杂的连接查询。在这个查询中,我真的很想应用 OFFSETLIMIT 以便在 Spring Batch Framework 中有效使用。

我经历了: How do I limit the number of rows returned by an Oracle query after ordering?

Alternatives to LIMIT and OFFSET for paging in Oracle

但事情对我来说不是很清楚。

我的查询

SELECT DEPT.ID rowobjid, DEPT.CREATOR createdby, DEPT.CREATE_DATE createddate, DEPT.UPDATED_BY updatedby, DEPT.LAST_UPDATE_DATE updateddate, 
DEPT.NAME name, DEPT.STATUS status, statusT.DESCR statusdesc, 
REL.ROWID_DEPT1 rowidDEPT1, REL.ROWID_DEPT2 rowidDEPT2, DEPT2.DEPT_FROM_VAL parentcid, DEPT2.NAME parentname 
FROM TEST.DEPT_TABLE DEPT 
LEFT JOIN TEST.STATUS_TABLE statusT ON DEPT.STATUS = statusT.STATUS 
LEFT JOIN TEST.C_REL_DEPT rel ON DEPT.ID=REL.ROWID_DEPT2 
LEFT JOIN TEST.DEPT_TABLE DEPT2 ON REL.ROWID_DEPT1=DEPT2.ID
ORDER BY rowobjid asc;

Above Query 给了我 1000 万条记录。

注意:两个数据库表都没有 PK,所以我需要使用 OFFSET 和 LIMIT。

【问题讨论】:

    标签: sql oracle oracle11g window-functions oracle11gr1


    【解决方案1】:

    您可以在 Oracle 11g 的子查询中使用 ROW_NUMBER() 等分析函数,假设您需要获得排名在第 3 和第 8 之间的行以便捕获 Oracle DB 中的 OFFSET 3 LIMIT 8 逻辑(实际上,这些条款包含在版本12c+)中,只要结果应按CREATE_DATE 分组并按部门的ID 排序:

    SELECT q.*
      FROM (SELECT DEPT.ID rowobjid,
                   DEPT.CREATOR createdby,
                   DEPT.CREATE_DATE createddate,
                   DEPT.UPDATED_BY updatedby,
                   DEPT.LAST_UPDATE_DATE updateddate,
                   DEPT.NAME name,
                   DEPT.STATUS status,
                   statusT.DESCR statusdesc,
                   REL.ROWID_DEPT1 rowidDEPT1,
                   REL.ROWID_DEPT2 rowidDEPT2,
                   DEPT2.DEPT_FROM_VAL parentcid,
                   DEPT2.NAME parentname,
                   ROW_NUMBER() OVER (PARTITION BY DEPT.CREATE_DATE ORDER BY DEPT.ID) AS rn
              FROM TEST.DEPT_TABLE DEPT
              LEFT JOIN TEST.STATUS_TABLE statusT
                ON DEPT.STATUS = statusT.STATUS
              LEFT JOIN TEST.C_REL_DEPT rel
                ON DEPT.ID = REL.ROWID_DEPT2
              LEFT JOIN TEST.DEPT_TABLE DEPT2
                ON REL.ROWID_DEPT1 = DEPT2.ID) q
     WHERE rn BETWEEN 3 AND 8;
    

    准确返回 6(8-3+1) 行。如果您需要包含关联(每个创建日期的部门标识的相同值),则应将 ROW_NUMBER() 替换为另一个名为 DENSE_RANK() 的窗口函数,因为查询的所有其他部分保持不变。 在这种情况下将返回至少 6 个记录。

    【讨论】:

    • 如何在这里找到 MIN 和 MAX rowCount 值以用于 Spring Batch 的分区?
    • 在这种情况下,考虑过滤掉 rn = 1,每当您按 dept.id 升序排序时,您会得到最小值,或者按降序排序,然后得到 dept.id 的最大值和对应的值作为回报在主查询 @JeffCook 中。 (你需要学习这个吗?)
    猜你喜欢
    • 2021-05-17
    • 2012-08-25
    • 1970-01-01
    • 2011-03-20
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    相关资源
    最近更新 更多