LIMIT, OFFSET și FETCH FIRST în PostgreSQL

Interogări și filtrare specifică Postgres PostgreSQL 8.4+ (WITH TIES din PostgreSQL 13+)

Limitează numărul de rânduri returnate și implementează paginarea sau extragerea top N cu egalități.

Sintaxă SQL
SELECT * FROM tabel ORDER BY coloana LIMIT n OFFSET m;nSELECT * FROM tabel ORDER BY coloana FETCH FIRST n ROWS WITH TIES;

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 și OFFSET fără ORDER BY: ordinea rândurilor în PostgreSQL se poate schimba după UPDATE sau VACUUM, ducând la duplicate sau rânduri lipsă între pagini.
  • Paginarea cu OFFSET foarte 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