Ce face LIMIT, OFFSET și FETCH FIRST
Clauzele LIMIT și OFFSET restrâng numărul de rânduri returnate de o interogare și sunt folosite frecvent pentru paginare și afișarea primelor N rezultate. Alternativa standardizată SQL:2008 este OFFSET m ROWS FETCH FIRST n ROWS ONLY.
Începând cu PostgreSQL 13, clauza FETCH FIRST n ROWS WITH TIES permite includerea automată a tuturor rândurilor aflate la egalitate pe ultima poziție conform ordinii din ORDER BY.
Clauze, operatori și argumente
| Clauză / Operator | Descriere |
|---|---|
LIMIT n |
Returnează cel mult n rânduri (LIMIT ALL sau LIMIT NULL elimină restricția). |
OFFSET m |
Sare peste primele m rânduri înainte de a începe returnarea rezultatelor. |
FETCH FIRST n ROWS ONLY |
Sintaxa SQL standard echivalentă cu LIMIT n. |
FETCH FIRST n ROWS WITH TIES |
Returnează primele n rânduri plus orice alte rânduri care au aceeași valoare în coloanele din ORDER BY ca și rândul al n-lea. |
Exemple
Exemplul 1: Paginare clasică cu LIMIT și OFFSET
Afișăm pagina a 2-a de articole (câte 3 articole pe pagină, deci sărim peste primele 3 cu OFFSET 3).
SELECT id, titlu, publicat_la
FROM articole
ORDER BY publicat_la DESC, id DESC
LIMIT 3 OFFSET 3;
Rezultat interogare
id | titlu | publicat_la
-----+----------------------------------+---------------------
118 | Optimizarea indecșilor în PG 17 | 2025-02-20 14:00:00
115 | Ghid complet pentru JSONB | 2025-02-18 10:30:00
112 | Tranzacții și niveluri de izolare| 2025-02-12 08:45:00
(3 rows)
Exemplul 2: Top 2 salarii incluzând egalitățile cu FETCH FIRST … WITH TIES
Dacă pe locul al 2-lea există doi angajați cu exact același salariu, WITH TIES îi returnează pe amândoi (în total 3 rânduri).
SELECT nume, departament, salariu
FROM angajati
ORDER BY salariu DESC
FETCH FIRST 2 ROWS WITH TIES;
Rezultat interogare
nume | departament | salariu
---------------+-------------+----------
Radu Ionescu | Arhitectură | 18500.00
Maria Stan | Backend | 16200.00
Vlad Dumitru | DevOps | 16200.00
(3 rows)
Greșeli frecvente
- Folosirea
LIMITșiOFFSETfărăORDER BY: ordinea rândurilor în PostgreSQL se poate schimba dupăUPDATEsauVACUUM, ducând la duplicate sau rânduri lipsă între pagini. - Paginarea cu
OFFSETfoarte mare (ex:OFFSET 500000): PostgreSQL trebuie să citească și să arunce toate cele 500.000 de rânduri anterioare; pentru tabele mari se recomandă paginarea prin cursor/keyset (WHERE id < ultimul_id ORDER BY id DESC LIMIT 20).
Comenzi și funcții înrudite
SELECT și DISTINCT ON: Extrage rânduri din tabele și păstrează doar primul rând pentru fiecare grup de valori distincte.ROW_NUMBER(), RANK() și DENSE_RANK(): Numerotează și clasifică rândurile în interiorul unei partiții fără a le colapsa ca GROUP BY.EXPLAIN (ANALYZE, BUFFERS): Afișează planul de execuție al optimizatorului, timpii reali pe fiecare nod și blocurile de memorie citite.