Применить OFFSET и LIMIT в ORACLE для сложных запросов на соединение? - PullRequest
1 голос
/ 21 июня 2020

Я использую Oracle 11g и имею сложный запрос на соединение. В этом запросе я действительно хотел применить OFFSET и LIMIT, чтобы их можно было эффективно использовать в Spring Batch Framework.

Я прошел через: Как мне ограничить количество строк, возвращаемых запрос Oracle после заказа? и

Альтернативы LIMIT и OFFSET для подкачки в 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;

Вышеупомянутый запрос дает мне 10 миллионов записей.

Примечание. Ни в одной из таблиц базы данных нет PK, поэтому мне нужно будет использовать OFFSET и LIMIT.

1 Ответ

1 голос
/ 22 июня 2020

Вы можете использовать функции Analyti c, такие как ROW_NUMBER(), в подзапросе для Oracle 11g, предполагая, что вам нужно получить строки с рангом от 3-го до 8-го, чтобы захватить OFFSET 3 LIMIT 8 logi c в базе данных Oracle ( действительно, эти пункты включены для версий 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 записей.

...