Чист 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