sql >> Databáze >  >> RDS >> PostgreSQL

Spusťte dotaz s LIMIT/OFFSET a získejte také celkový počet řádků

Ano. S jednoduchou funkcí okna:

SELECT *, count(*) OVER() AS full_count
FROM   tbl
WHERE  /* whatever */
ORDER  BY col1
OFFSET ?
LIMIT  ?

Uvědomte si, že náklady budou podstatně vyšší než bez celkového počtu, ale obvykle stále levnější než dva samostatné dotazy. Postgres musí skutečně spočítat všechny řádky v obou směrech, což si vyžádá náklady v závislosti na celkovém počtu kvalifikujících řádků. Podrobnosti:

  • Nejlepší způsob, jak získat počet výsledků před použitím LIMIT

Nicméně , jak zdůraznil Dani, když OFFSET je alespoň tak velký jako počet řádků vrácených ze základního dotazu, nejsou vráceny žádné řádky. Takže také nezískáme full_count .

Pokud to není přijatelné, je to možné řešení, jak vždy vrátit celý počet bude s CTE a 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;

Získáte jeden řádek hodnot NULL s full_count připojeno, pokud OFFSET je příliš velký. Jinak je připojen ke každému řádku jako v prvním dotazu.

Pokud je řádek se všemi hodnotami NULL možným platným výsledkem, musíte zaškrtnout offset >= full_count k jednoznačnému určení původu prázdného řádku.

To stále provede základní dotaz pouze jednou. Ale přidává více režie k dotazu a platí pouze tehdy, pokud je to méně než opakování základního dotazu pro počet.

Pokud jsou k dispozici indexy podporující konečné pořadí řazení, může se vyplatit zahrnout ORDER BY v CTE (redundantně).



  1. Jak vybrat pouze první řádky pro každou jedinečnou hodnotu sloupce?

  2. 7 způsobů, jak může Microsoft Access pomoci vaší firmě

  3. MySQL Server zmizel při importu velkého souboru SQL

  4. MySQL s Node.js