Salta el contingut

Filtres i ordenació

ORDER BY

La clàusula ORDER BY ordena el resultat d'una consulta. Sense ORDER BY, l'ordre de les files no està garantit (el SGBD pot retornar-les en qualsevol ordre, depenent de l'emmagatzematge físic i del pla d'execució).

-- Ordenació ascendent (per defecte)
SELECT nom, cognoms, data_alta FROM clients ORDER BY cognoms;

-- Ordenació descendent
SELECT nom, data_alta FROM clients ORDER BY data_alta DESC;

-- Ordenació per múltiples columnes
SELECT nom, cognoms, poblacio FROM clients ORDER BY poblacio, cognoms, nom;

-- Ordenació per expressió
SELECT nom, cognoms FROM clients ORDER BY LOWER(cognoms);

-- Ordenació per posició de columna (antiquat, evitar)
SELECT nom, cognoms, preu FROM productes ORDER BY 3 DESC;

-- NULL primer o al final (PostgreSQL)
SELECT nom, ultima_connexio FROM usuaris ORDER BY ultima_connexio NULLS LAST;
SELECT nom, cognoms, data_alta FROM clients ORDER BY cognoms ASC;

SELECT nom, data_alta FROM clients ORDER BY data_alta DESC;

SELECT nom, cognoms, poblacio FROM clients ORDER BY poblacio, cognoms, nom;

-- MySQL: NULLS LAST és el comportament per defecte en DESC
SELECT nom, ultima_connexio FROM usuaris ORDER BY ultima_connexio DESC;
SELECT nom, cognoms, data_alta FROM clients ORDER BY cognoms ASC;

SELECT nom, data_alta FROM clients ORDER BY data_alta DESC;

-- SQL Server 2022+ suporta NULLS FIRST / NULLS LAST
SELECT nom, ultima_connexio FROM usuaris ORDER BY ultima_connexio NULLS LAST;
SELECT nom, cognoms, data_alta FROM clients ORDER BY cognoms ASC;

SELECT nom, data_alta FROM clients ORDER BY data_alta DESC;

-- Ordenació per expressió
SELECT nom, cognoms FROM clients ORDER BY LOWER(cognoms);

-- NULLS FIRST / NULLS LAST suportat a Oracle
SELECT nom, ultima_connexio FROM usuaris ORDER BY ultima_connexio NULLS LAST;

LIMIT / FETCH FIRST / TOP

Limitar el nombre de files retornades és essencial quan treballem amb taules grans.

-- Els 10 productes mes cars
SELECT nom, preu FROM productes ORDER BY preu DESC LIMIT 10;

-- OFFSET: saltar les primeres N files (per a paginació)
SELECT nom, preu FROM productes ORDER BY preu DESC LIMIT 10 OFFSET 20;
-- Retorna files 21-30

-- Sintaxi SQL estàndard (PostgreSQL 8.4+)
SELECT nom, preu FROM productes ORDER BY preu DESC
FETCH FIRST 10 ROWS ONLY;
-- Els 10 productes mes cars
SELECT nom, preu FROM productes ORDER BY preu DESC LIMIT 10;

-- Paginació: LIMIT offset, count
SELECT nom, preu FROM productes ORDER BY preu DESC LIMIT 20, 10;
-- Retorna files 21-30

-- Sintaxi alternativa
SELECT nom, preu FROM productes ORDER BY preu DESC LIMIT 10 OFFSET 20;
-- TOP: només a SQL Server
SELECT TOP 10 nom, preu FROM productes ORDER BY preu DESC;

-- TOP amb percentatge
SELECT TOP 10 PERCENT nom, preu FROM productes ORDER BY preu DESC;

-- SQL estàndard (SQL Server 2012+), recomanat per paginació
SELECT nom, preu FROM productes ORDER BY preu DESC
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
-- FETCH FIRST (Oracle 12c+, sintaxi SQL estàndard)
SELECT nom, preu FROM productes ORDER BY preu DESC
FETCH FIRST 10 ROWS ONLY;

-- Paginació amb OFFSET (Oracle 12c+)
SELECT nom, preu FROM productes ORDER BY preu DESC
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

-- Mètode clàssic amb ROWNUM (Oracle 11g i anterior)
SELECT nom, preu FROM (
    SELECT nom, preu FROM productes ORDER BY preu DESC
) WHERE ROWNUM <= 10;

LIMIT sense ORDER BY

Usar LIMIT o TOP sense ORDER BY retorna un subconjunt arbitrari de files. En la majoria de casos pràctics, volem limitar el resultat d'una manera determinista, per la qual cosa gairebé sempre cal un ORDER BY quan usem LIMIT.


Operadors lògics: AND, OR, NOT

Es poden combinar múltiples condicions en el WHERE:

-- AND: les dues condicions han de ser TRUE
SELECT * FROM productes WHERE estoc > 0 AND preu < 50;

-- OR: almenys una condició ha de ser TRUE
SELECT * FROM clients WHERE poblacio = 'Blanes' OR poblacio = 'Lloret de Mar';

-- NOT: nega la condició
SELECT * FROM comandes WHERE NOT estat = 'cancel·lada';
-- Equivalent a:
SELECT * FROM comandes WHERE estat <> 'cancel·lada';

-- Combinació amb parèntesis (important l'ordre de precedència: NOT > AND > OR)
SELECT * FROM productes
WHERE (categoria = 'electronics' OR categoria = 'informàtica')
  AND preu BETWEEN 100 AND 500
  AND estoc > 0;

IN, BETWEEN, IS NULL

IN

IN comprova si un valor és en una llista. Equivalent a múltiples OR però mes llegible:

-- Equivalent:
WHERE estat = 'pendent' OR estat = 'confirmada' OR estat = 'processant'
-- Més llegible:
WHERE estat IN ('pendent', 'confirmada', 'processant')

-- NOT IN
WHERE estat NOT IN ('cancel·lada', 'retornada')

-- IN amb subconsulta (ho veurem a subconsultes)
WHERE id_client IN (SELECT id_client FROM clients WHERE poblacio = 'Blanes')

BETWEEN

BETWEEN a AND b és inclusiu pels dos extrems (equivalent a >= a AND <= b):

-- Preus entre 10 i 100 (inclosos)
WHERE preu BETWEEN 10.00 AND 100.00

-- Dates en un rang
WHERE data_com BETWEEN '2025-01-01' AND '2025-12-31'

-- NOT BETWEEN
WHERE preu NOT BETWEEN 10.00 AND 100.00

IS NULL i IS NOT NULL

NULL representa un valor absent o desconegut. Cal usar IS NULL / IS NOT NULL per comprovar-ho, mai = NULL:

-- Clients sense telèfon registrat
SELECT nom, cognoms FROM clients WHERE telefon IS NULL;

-- Clients amb telèfon registrat
SELECT nom, cognoms FROM clients WHERE telefon IS NOT NULL;

-- Errors comuns:
WHERE telefon = NULL    -- INCORRECTE: sempre és NULL/unknown, no filtra res
WHERE telefon != NULL   -- INCORRECTE: igual

AC0372/04/02 — Miniactivitat

RA4 · CA4.2, CA4.6

Escriviu consultes per a:

  1. Els 5 clients mes recents (per data_alta descendent), mostrant nom complet i email.
  2. Productes amb estoc entre 5 i 50 unitats, ordenats per estoc ascendent.
  3. Clients de Blanes o de Lloret de Mar amb email registrat, ordenats alfabèticament per cognoms.
  4. Productes sense preu (NULL) o amb estoc = 0.
  5. Tots els estats de comandes distints, ordenats alfabèticament.