Чист SQL
Нещата се промениха от 2008 г. Можете да използвате функция за прозорец, за да получите пълния брой и ограничен резултат в една заявка. Въведен с PostgreSQL 8.4 през 2009 г.
SELECT foo
, count(*) OVER() AS full_count
FROM bar
WHERE <some condition>
ORDER BY <some col>
LIMIT <pagesize>
OFFSET <offset>;
Имайте предвид, че това може да бъде значително по-скъпо, отколкото без общия брой . Всички редове трябва да бъдат преброени и възможен пряк път, вземащ само горните редове от съответстващ индекс, може вече да не е полезен.
Няма голямо значение при малки таблици или full_count
<=OFFSET
+ LIMIT
. Има значение за значително по-голям full_count
.
Ъглов калъф :когато OFFSET
е поне толкова голям, колкото броя на редовете от основната заявка, без ред се връща. Така че вие също не получавате full_count
. Възможна алтернатива:
- Изпълнете заявка с LIMIT/OFFSET и получете общия брой редове
Последователност от събития в SELECT
заявка
(0. CTE се оценяват и материализират отделно. В Postgres 12 или по-нова версия, плановникът може да вгради тези като подзаявки, преди да започне работа.) Не тук.
WHERE
клауза (иJOIN
условия, макар и никакви във вашия пример) филтрирайте квалифициращите редове от основната таблица(и). Останалото се основава на филтрираното подмножество.
( 2. GROUP BY
и агрегатните функции ще отидат тук.) Не тук.
( 3. Други SELECT
списъчните изрази се оценяват въз основа на групирани / обобщени колони.) Не тук.
-
Функциите на прозореца се прилагат в зависимост от
OVER
клауза и спецификацията на рамката на функцията. Простиятcount(*) OVER()
се основава на всички квалификационни редове. -
ORDER BY
( 6. DISTINCT
или DISTINCT ON
би отишъл тук.) Не тук.
LIMIT
/OFFSET
се прилагат въз основа на установения ред за избор на редове за връщане.
LIMIT
/ OFFSET
става все по-неефективно с нарастващ брой редове в таблицата. Помислете за алтернативни подходи, ако имате нужда от по-добра производителност:
- Оптимизиране на заявката с OFFSET върху голяма таблица
Алтернативи за получаване на окончателно броене
Има напълно различни подходи за получаване на броя на засегнатите редове (не пълният брой преди OFFSET
&LIMIT
бяха приложени). Postgres има вътрешно счетоводство колко реда са засегнати от последната SQL команда. Някои клиенти могат да имат достъп до тази информация или сами да броят редове (като psql).
Например, можете да извлечете броя на засегнатите редове в plpgsql веднага след изпълнение на SQL команда с:
GET DIAGNOSTICS integer_var = ROW_COUNT;
Подробности в ръководството.
Или можете да използвате pg_num_rows
в PHP . Или подобни функции в други клиенти.
Свързано:
- Изчислете броя на редовете, засегнати от груповата заявка в PostgreSQL