Я использую Oracle 10g и следующую парадигму, чтобы получить страницу из 15 результатов за раз (так что, когда пользователь просматривает страницу 2 результата поиска, он видит записи 16-30).
select *
from
( select rownum rnum, a.*
from (my_query) a
where rownum <= 30 )
where rnum > 15;
Прямо сейчас мне нужно запустить отдельный оператор SQL, чтобы выполнить «выбор подсчета» для «my_query», чтобы получить общее количество результатов для my_query (чтобы я мог показать его пользователю и использовать его выяснить общее количество страниц и т. д.).
Есть ли способ получить общее количество результатов, не делая этого с помощью второго запроса, то есть, получая его из запроса выше? Я попытался добавить "max (rownum)", но, похоже, он не работает (я получаю ошибку [ORA-01747], которая, кажется, указывает на то, что мне не нравится иметь ключевое слово rownum в группе).
Мое обоснование желания получить это из исходного запроса, а не делать это в отдельном операторе SQL, заключается в том, что «my_query» является дорогим запросом, поэтому я бы не стал его выполнять дважды (один раз, чтобы получить счетчик, и один раз чтобы получить страницу данных), если мне не нужно; но какое бы решение я ни нашел, чтобы получить количество результатов в одном запросе (и в то же время получить нужную мне страницу данных), не следует добавлять много, если возможно, дополнительные накладные расходы. Пожалуйста, сообщите.
Вот именно то, что я пытаюсь сделать, для чего я получаю ошибку ORA-01747, потому что я считаю, что мне не нравится иметь ROWNUM в группе. Обратите внимание: если есть другое решение, которое не использует max (ROWNUM), но что-то еще, это тоже прекрасно. Это решение было моей первой мыслью о том, что может сработать.
SELECT * FROM (SELECT r.*, ROWNUM RNUM, max(ROWNUM)
FROM (SELECT t0.ABC_SEQ_ID AS c0, t0.FIRST_NAME, t0.LAST_NAME, t1.SCORE
FROM ABC t0, XYZ t1
WHERE (t0.XYZ_ID = 751) AND
t0.XYZ_ID = t1.XYZ_ID
ORDER BY t0.RANK ASC) r WHERE ROWNUM <= 30 GROUP BY r.*, ROWNUM) WHERE RNUM > 15
--------- РЕДАКТИРОВАТЬ --------
Обратите внимание, на основании первого комментария я попробовал следующее, которое, кажется, работает. Я не знаю, насколько хорошо он работает по сравнению с другими решениями (я ищу решение, которое удовлетворяет моим требованиям, но работает лучше). Например, когда я запускаю это, это занимает 16 секунд. Когда я вынимаю COUNT (*) OVER () RESULT_COUNT, это занимает всего 7 секунд:
SELECT * FROM (SELECT r.*, ROWNUM RNUM, )
FROM (SELECT COUNT(*) OVER () RESULT_COUNT,
t0.ABC_SEQ_ID AS c0, t0.FIRST_NAME, t1.SCORE
FROM ABC t0, XYZ t1
WHERE (t0.XYZ_ID = 751) AND t0.XYZ_ID = t1.XYZ_ID
ORDER BY t0.RANK ASC) r WHERE ROWNUM <= 30) WHERE RNUM > 1
План объяснения меняется с выполнения SORT (ORDER BY STOP KEY) на выполнение WINDOW (SORT).
До:
SELECT STATEMENT ()
COUNT (STOPKEY)
VIEW ()
SORT (ORDER BY STOPKEY)
NESTED LOOPS ()
TABLE ACCESS (BY INDEX ROWID) XYZ
INDEX (UNIQUE SCAN) XYZ_ID
TABLE ACCESS (FULL) ABC
После того, как: * * тысяча двадцать-одна
SELECT STATEMENT ()
COUNT (STOPKEY)
VIEW ()
WINDOW (SORT)
NESTED LOOPS ()
TABLE ACCESS (BY INDEX ROWID) XYZ
INDEX (UNIQUE SCAN) XYZ_ID
TABLE ACCESS (FULL) ABC