Я использую Oracle 10g и следующую парадигму, чтобы получить страницу из 15 результатов за время (так что, когда пользователь смотрит на страницу 2 результата поиска, они видят записи 16-30).
select *
from
( select rownum rnum, a.*
from (my_query) a
where rownum <= 30 )
where rnum > 15;
Сейчас мне нужно запустить отдельный оператор SQL, чтобы сделать "select count" на "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
--------- EDIT -------- Примечание. Основываясь на первом комментарии, я попробовал следующее, которое, похоже, работает. Я не знаю, насколько хорошо он работает в сравнении с другими решениями (я ищу решение, которое удовлетворяет моему требованию, но делает все возможное). Например, когда я запускаю это, это занимает 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), чтобы сделать ОКНО (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