Да С проста функция за прозорец:
SELECT *, count(*) OVER() AS full_count
FROM tbl
WHERE /* whatever */
ORDER BY col1
OFFSET ?
LIMIT ?
Имайте предвид, че цената ще бъде значително по-висока, отколкото без общия брой, но обикновено все още по-евтина от две отделни заявки. Postgres трябва всъщност да преброи всички редове така или иначе, което налага цена в зависимост от общия брой квалифицирани редове. Подробности:
- Най-добрият начин да получите резултат, преди да бъде приложен LIMIT
Въпреки това , както посочи Дани, когато OFFSET
е поне толкова голям, колкото броя на редовете, върнати от основната заявка, не се връщат редове. Така че ние също не получаваме full_count
.
Ако това не е приемливо, възможнозаобиколно решение винаги да връща пълния брой ще бъде с CTE и OUTER JOIN
:
WITH cte AS (
SELECT *
FROM tbl
WHERE /* whatever */
)
SELECT *
FROM (
TABLE cte
ORDER BY col1
LIMIT ?
OFFSET ?
) sub
RIGHT JOIN (SELECT count(*) FROM cte) c(full_count) ON true;
Получавате един ред NULL стойности с full_count
добавено, ако OFFSET
е твърде голям. В противен случай се добавя към всеки ред, както в първата заявка.
Ако ред с всички стойности NULL е възможен валиден резултат, трябва да проверите offset >= full_count
за да изключите произхода на празния ред.
Това все още изпълнява основната заявка само веднъж. Но това добавя повече режийни разходи към заявката и се плаща само ако това е по-малко от повтарянето на основната заявка за броя.
Ако са налични индекси, поддържащи окончателния ред на сортиране, може да си струва да включите ORDER BY
в CTE (излишно).