Les taules de BotigaVerda no tenen files duplicades: cadascuna té la seva clau primària id, així que no n'hi ha dues d'iguals. I tanmateix, tan bon punt projectes només una part de les columnes, comencen a aparèixer repeticions per tot arreu. Preguntar "a quins països tinc clients?" sobre una taula de quinze files retorna quinze respostes quan només hi ha tres països diferents. En aquesta lliçó aprendràs per què passa, com ho resol DISTINCT, per què actua sobre la combinació completa de columnes del SELECT (el malentès més habitual del mòdul), on encaixa a l'ordre lògic d'execució, i quan l'aparició de DISTINCT en una consulta és en realitat el senyal que la consulta està mal plantejada.
Contingut
- Per què apareixen files repetides
DISTINCTsobre una columnaDISTINCTsobre diverses columnes: el malentès clàssic- On encaixa
DISTINCTa l'ordre lògic DISTINCTcombinat ambWHEREi ambORDER BYCOUNT(DISTINCT columna): un avanç del mòdul 4DISTINCT ON: l'extensió de PostgreSQL- El cost de
DISTINCTi quan delata un error - Errors habituals i consells
- Exercicis
- Conclusió
- Per què apareixen files repetides
Comencem pel problema:
| pais |
|---|
| Espanya |
| Espanya |
| Espanya |
| Espanya |
| Espanya |
| Espanya |
| Portugal |
| Portugal |
| França |
| França |
| Espanya |
| Espanya |
| Espanya |
| Espanya |
| Espanya |
15 files. Una per client, perquè SELECT retorna una fila de resultat per cada fila d'origen. La projecció ha eliminat les columnes que feien única cada fila (id, email, nom...), i el que queda es repeteix.
És important entendre que això no és una fallada de les dades. Al model relacional pur una relació és un conjunt i no admet duplicats, però SQL no treballa amb conjunts sinó amb multiconjunts (bags): permet repeticions i només les elimina si li ho demanes explícitament. Va ser una decisió pragmàtica dels dissenyadors del llenguatge: eliminar duplicats costa temps, i a la majoria de les consultes no cal.
El mateix amb les ciutats:
Retorna 15 files amb València quatre vegades i Barcelona dues.
DISTINCT sobre una columna
DISTINCT sobre una columnaLa paraula clau DISTINCT s'escriu immediatament després de SELECT i elimina les files repetides del resultat:
| pais |
|---|
| Espanya |
| Portugal |
| França |
3 files. Ara sí que has respost a la pregunta "a quins països tinc clients?".
| ciutat |
|---|
| València |
| Castelló |
| Madrid |
| Barcelona |
| Lisboa |
| Porto |
| Lió |
| París |
| Alacant |
| Sevilla |
| Saragossa |
11 files de les 15: València hi apareixia 4 vegades i Barcelona 2.
Un altre cas útil: saber quins mètodes de pagament es fan servir realment. La restricció CHECK de la taula n'admet quatre, però es fan servir tots?
| metode_pagament |
|---|
| targeta |
| transferencia |
| paypal |
| contrareemborsament |
Els quatre. I els estats:
| estat |
|---|
| lliurat |
| enviat |
| pagat |
| pendent |
| cancellat |
Els cinc valors del domini hi són representats.
Molt important:
DISTINCTno ordena. Els resultats de dalt surten en un ordre que PostgreSQL tria segons com hagi eliminat els duplicats (normalment amb una taula hash, l'ordre de la qual és impredictible). Podries veure perfectamentFrança, Espanya, Portugal. Si vols un ordre concret,ORDER BY(secció 5).
Dos detalls de sintaxi:
DISTINCTafecta tota la llista de columnes, no la que té al costat.SELECT DISTINCT pais, ciutatno és "el país diferent i la ciutat": és la secció 3.DISTINCT(pais)funciona, però és enganyós: aquests parèntesis són els d'una expressió, no els d'una funció.SELECT DISTINCT (pais), ciutatcontinua aplicantDISTINCTa les dues columnes. No escriguisDISTINCTamb parèntesis; indueix a error qui ho llegeixi.
I un apunt sobre nuls: per a DISTINCT, tots els NULL compten com un mateix valor i es col·lapsen en una sola fila. És una excepció deliberada a la regla que NULL no és igual a NULL, i la veuràs a l'exercici 3.
DISTINCT sobre diverses columnes: el malentès clàssic
DISTINCT sobre diverses columnes: el malentès clàssicAquesta és la part que cal interioritzar bé:
| pais | ciutat |
|---|---|
| Espanya | València |
| Espanya | Castelló |
| Espanya | Madrid |
| Espanya | Barcelona |
| Espanya | Alacant |
| Espanya | Sevilla |
| Espanya | Saragossa |
| Portugal | Lisboa |
| Portugal | Porto |
| França | Lió |
| França | París |
11 files, i Espanya hi apareix set vegades. No havíem dit que DISTINCT elimina duplicats?
Els ha eliminat. El que passa és que DISTINCT compara la fila completa, no columna per columna. (Espanya, València) i (Espanya, Madrid) són dues files diferents, encara que comparteixin el primer valor. Només s'elimina una fila si tots els seus valors coincideixen amb els d'una altra: (Espanya, València) apareixia quatre vegades a la taula i n'ha quedat una.
| El que molta gent creu que fa | El que fa de debò |
|---|---|
"Un valor diferent de pais, i per a cadascun la ciutat" |
Cada combinació diferent de (pais, ciutat) |
| Hauria de retornar 3 files | En retorna 11 |
Pensa-hi així: DISTINCT mira la fila del resultat com si fos una tupla i es pregunta "ja he vist exactament aquesta tupla?".
Un altre exemple, aquesta vegada sobre el catàleg: quines combinacions de categoria i proveïdor existeixen?
Amb ORDER BY per poder llegir-ho (ho justifiquem a la secció 5):
| categoria_id | proveidor_id |
|---|---|
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
| 3 | 3 |
| 3 | 5 |
| 4 | 1 |
| 4 | 2 |
| 4 | 3 |
| 5 | 4 |
| 5 | 5 |
| 6 | 5 |
12 combinacions a partir de 20 productes. Es llegeix molta informació de negoci en aquesta taula: la categoria 4 (Begudes) es proveeix de tres proveïdors diferents, mentre que la 6 (Complements) depèn d'un de sol, i aquest únic proveïdor —el 5, EcoNordic— és precisament el que està inactiu. Sense DISTINCT hauries hagut de llegir 20 files per arribar a la mateixa conclusió.
Si de debò vols "un país per fila i alguna cosa de les seves ciutats", DISTINCT no és l'eina: necessites agrupar, que és GROUP BY (lliçó 04-05). La diferència conceptual, per tenir-la clara des d'ara:
| Eina | Què fa | Lliçó |
|---|---|---|
DISTINCT |
Elimina files repetides del resultat tal com està | 02-04 |
GROUP BY |
Col·lapsa grups de files en una de sola i permet calcular sobre cada grup (comptar, sumar, fer mitjanes) | 04-05 |
- On encaixa
DISTINCT a l'ordre lògic
DISTINCT a l'ordre lògicDISTINCT s'aplica després de la projecció del SELECT i abans d'ORDER BY. Això és coherent: només es poden comparar files duplicades un cop se sap quines columnes contenen.
flowchart LR
A["1 · FROM<br/>clients<br/>15 files"] --> B["2 · WHERE<br/>filtra files"]
B --> C["3 · SELECT<br/>projecta pais, ciutat"]
C --> D["3b · DISTINCT<br/>elimina duplicats<br/>11 files"]
D --> E["4 · ORDER BY"]
E --> F["5 · LIMIT"]
D'aquí se'n dedueixen dues regles que veuràs en acció de seguida:
| Regla | Conseqüència |
|---|---|
WHERE s'executa abans que DISTINCT |
Primer es filtra, després es deduplica. Mai al revés |
ORDER BY s'executa després que DISTINCT |
Només pots ordenar per columnes que hagin sobreviscut a la projecció |
DISTINCT combinat amb WHERE i amb ORDER BY
DISTINCT combinat amb WHERE i amb ORDER BY5.1. Amb WHERE
| ciutat |
|---|
| València |
| Castelló |
| Madrid |
| Barcelona |
| Alacant |
| Sevilla |
| Saragossa |
7 ciutats espanyoles. L'ordre és: FROM porta les 15 files → WHERE en deixa 11 → SELECT projecta ciutat → DISTINCT redueix a 7.
5.2. Amb ORDER BY
| pais |
|---|
| Espanya |
| França |
| Portugal |
Ara l'ordre sí que està garantit (alfabètic). ORDER BY és la lliçó següent; aquí el fem servir només per fer llegibles els resultats.
5.3. La restricció: només pots ordenar per allò que hagis seleccionat
Prova això:
ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 3: ORDER BY ciutat;
^El missatge és explícit i la raó és lògica, no arbitrària. Després del DISTINCT només queden tres files: Espanya, Portugal i França. La fila Espanya procedeix d'onze files originals amb onze ciutats diferents. Per quina de les onze caldria ordenar-la? La pregunta no té resposta, així que PostgreSQL es nega a inventar-se'n una.
La regla, memoritzable: amb SELECT DISTINCT, tot el que aparegui a ORDER BY ha d'aparèixer també a la llista del SELECT.
Si el que volies era ordenar els països per algun criteri derivat de les ciutats, necessites GROUP BY i una funció d'agregació (mòdul 4).
Un cas freqüent que també falla per això: ordenar per una columna que no projectes.
Mateix missatge. I si l'"arregles" afegint preu al SELECT, canvies la pregunta: passaries de "categories diferents" (6 files) a "combinacions diferents de categoria i preu" (20 files, perquè gairebé tots els preus són únics). Afegir columnes al SELECT debilita el DISTINCT.
COUNT(DISTINCT columna): un avanç del mòdul 4
COUNT(DISTINCT columna): un avanç del mòdul 4Moltes vegades no vols la llista de valors diferents, sinó quants n'hi ha. Per a això es combina DISTINCT amb la funció d'agregació COUNT:
SELECT COUNT(*) AS files,
COUNT(ciutat) AS ciutats_no_nules,
COUNT(DISTINCT ciutat) AS ciutats_diferents,
COUNT(DISTINCT pais) AS paisos_diferents
FROM clients;| files | ciutats_no_nules | ciutats_diferents | paisos_diferents |
|---|---|---|---|
| 15 | 15 | 11 | 3 |
Fixa't en la diferència entre les tres variants de COUNT:
| Expressió | Què compta |
|---|---|
COUNT(*) |
Files, sense mirar valors |
COUNT(columna) |
Valors no nuls d'aquella columna |
COUNT(DISTINCT columna) |
Valors diferents i no nuls |
Aquí COUNT(ciutat) coincideix amb COUNT(*) perquè a BotigaVerda cap client no té la ciutat a nul, però la columna admet nuls i en una altra base de dades la diferència seria visible.
No hi aprofundim més: COUNT, SUM, AVG, MIN i MAX són la lliçó 04-04, i l'agrupació per categories, la 04-05. Ho deixem aquí simplement perquè és l'aplicació més freqüent de DISTINCT en el treball real d'anàlisi.
DISTINCT ON: l'extensió de PostgreSQL
DISTINCT ON: l'extensió de PostgreSQLPostgreSQL afegeix una variant que no és a l'estàndard SQL i que és enormement útil: DISTINCT ON (columnes) conserva la primera fila de cada grup de valors, segons l'ordre que tu indiquis.
Problema: el producte més car de cada categoria.
SELECT DISTINCT ON (categoria_id)
categoria_id,
id,
nom,
preu
FROM productes
ORDER BY categoria_id, preu DESC;| categoria_id | id | nom | preu |
|---|---|---|---|
| 1 | 1 | Oli d'oliva verge extra 500 ml | 12.50 |
| 2 | 6 | Crema facial d'àloe vera 50 ml | 18.90 |
| 3 | 13 | Espelmes de cera de soja (pack 2) | 13.75 |
| 4 | 15 | Te verd matcha cerimonial 30 g | 22.00 |
| 5 | 19 | Desodorant natural en barra 50 g | 7.80 |
| 6 | 20 | Càpsules d'espirulina 120 u | 16.40 |
Sis files, una per categoria, amb el producte més car de cadascuna. Això amb DISTINCT a seques és impossible.
Com funciona, pas a pas:
ORDER BY categoria_id, preu DESCordena totes les files: primer agrupades per categoria, i dins de cada categoria, de més car a més barat.DISTINCT ON (categoria_id)recorre aquest resultat ordenat i es queda amb la primera fila de cada valor decategoria_id, descartant la resta.
D'aquí en surt la regla d'or:
Les columnes de
DISTINCT ON (...)han de ser les primeres de l'ORDER BY, i en el mateix ordre. Si no ho són, PostgreSQL dona error; i si l'ORDER BYno desempata bé el que ve després, la fila triada dins de cada grup és impredictible.
Si canvies preu DESC per preu, obtens el producte més barat de cada categoria:
SELECT DISTINCT ON (categoria_id)
categoria_id, id, nom, preu
FROM productes
ORDER BY categoria_id, preu;| categoria_id | id | nom | preu |
|---|---|---|---|
| 1 | 5 | Tomàquet triturat ecològic 400 g | 1.95 |
| 2 | 9 | Bàlsam labial de calèndula 15 ml | 4.60 |
| 3 | 11 | Fregall vegetal de lufa (pack 3) | 5.50 |
| 4 | 14 | Infusió de camamilla ecològica 20 u | 3.25 |
| 5 | 18 | Raspall de dents de bambú | 3.50 |
| 6 | 20 | Càpsules d'espirulina 120 u | 16.40 |
El patró "la fila més X de cada grup" (l'última comanda de cada client, la ressenya més recent de cada producte, el preu més alt de cada categoria) és un dels més demanats al món real, i DISTINCT ON el resol en tres línies.
Portabilitat:
| Motor | Com es fa |
|---|---|
| PostgreSQL | DISTINCT ON (...) amb l'ORDER BY adequat |
| Estàndard SQL / MySQL 8 / SQL Server / Oracle | Funció de finestra: ROW_NUMBER() OVER (PARTITION BY categoria_id ORDER BY preu DESC) i quedar-se amb la fila 1 |
| SQLite | Funció de finestra (des de 3.25) o el truc de MAX() amb GROUP BY |
| MySQL 5.7 | Subconsulta correlacionada (mòdul 7) |
La forma portable amb funcions de finestra s'estudia a la lliçó 10-03, i és la que hauràs de fer servir si el teu SQL ha de funcionar fora de PostgreSQL. Mentre treballis amb PostgreSQL, DISTINCT ON és més curt i sol ser més ràpid.
- El cost de
DISTINCT i quan delata un error
DISTINCT i quan delata un errorDISTINCT no és gratis. Per saber si una fila està repetida, PostgreSQL ha de comparar totes les files entre si, i ho fa d'una d'aquestes dues maneres:
| Estratègia | Com funciona | Cost |
|---|---|---|
HashAggregate |
Construeix una taula hash amb les files ja vistes | Ràpida, però consumeix memòria proporcional al nombre de valors diferents |
Sort + Unique |
Ordena totes les files i elimina les contigües iguals | Requereix ordenar tot el conjunt; si no cap a la memòria, escriu a disc |
Amb 15 files és instantani. Amb deu milions de files i una columna de text llarg, un DISTINCT innecessari pot convertir una consulta de 50 ms en una de 30 segons. Ho podràs veure tu mateix amb EXPLAIN al mòdul 8.
I hi ha una cosa més important que el cost: un DISTINCT inesperat sol ser el símptoma d'una consulta mal plantejada, no la solució. El cas típic arriba al mòdul 3:
-- Avanç del mòdul 3: "clients que han fet alguna comanda"
SELECT c.nom, c.cognoms
FROM clients AS c
JOIN comandes AS co ON co.client_id = c.id;Aquesta consulta retorna 20 files i no 12, perquè la Lucía Martínez té tres comandes (1, 5 i 15) i hi apareix tres vegades. El reflex natural és afegir DISTINCT i quedar-se tranquil. Però el DISTINCT no arregla res: amaga el fet que la unió ha multiplicat les files. Si demà afegeixes una columna al SELECT —per exemple co.data_comanda—, les files es tornen a duplicar i el DISTINCT deixa de servir.
La llista de comprovació quan et descobreixis escrivint DISTINCT:
- Hi ha duplicats de debò, o els està creant la meva consulta? Si és el segon cas, el problema és a la unió, no a la projecció.
- El que vull és "valors diferents" o "un resultat per grup"? Si és el segon, és
GROUP BY(04-05) oDISTINCT ON(secció 7). - Vull comprovar existència? Llavors l'eina correcta és
EXISTS(lliçó 07-03), que no multiplica files i per tant no necessita deduplicar. - Estic deduplicant per columnes que no necessito? Treure del
SELECTuna columna innecessària pot fer que elDISTINCTsobri.
DISTINCT és perfectament legítim per al que hem fet en aquesta lliçó: preguntar "quins valors diferents hi ha en aquesta columna?". El que és sospitós és fer-lo servir com a pedaç.
Errors habituals i consells
- Creure que
DISTINCT columna1, columna2deduplica només per la primera. Deduplica per la combinació completa. És el malentès número u. - Escriure
DISTINCT(columna). Funciona, però fa pensar queDISTINCTés una funció que s'aplica a aquella columna. No ho és. EscriuDISTINCT columna1, columna2. - Esperar que
DISTINCTordeni. No ordena. Si necessites ordre,ORDER BY. - Ordenar per una columna que no és en un
SELECT DISTINCT.ORDER BY expressions must appear in select list. I "arreglar-ho" afegint la columna canvia la pregunta. - Afegir columnes i no adonar-se que el
DISTINCTdeixa de servir. Cada columna nova pot multiplicar les files del resultat. - Fer servir
DISTINCTper tapar duplicats creats per unJOIN. Corregeix la consulta, no el símptoma. - Oblidar que els
NULLs'agrupen.DISTINCTretorna una sola fila ambNULL, encara que n'hi hagi cent. - Fer servir
DISTINCT ONsense l'ORDER BYcorrecte. La fila que es conserva de cada grup és llavors impredictible: avui una, demà una altra. - Consell: per comptar valors únics,
COUNT(DISTINCT col)en comptes de portar-te la llista i comptar-la a mà. - Consell: fes servir
DISTINCTcom a eina d'exploració.SELECT DISTINCT estat FROM comandes;és la manera més ràpida de saber quins valors conté realment una columna, inclosos els que no hi haurien de ser. - Consell: si
DISTINCTés lent, mira el pla.EXPLAIN(mòdul 8) et dirà si està ordenant a disc.
Exercicis
Exercici 1
Màrqueting vol saber des de quines ciutats s'ha comprat a Portugal i França. Escriu una consulta que retorni les combinacions diferents de pais i ciutat dels clients que no siguin d'Espanya, ordenades per país i ciutat. Explica per què el resultat té el nombre de files que té.
Exercici 2
Un company escriu aquesta consulta per saber quants mètodes de pagament diferents es fan servir i se sorprèn del resultat:
Explica què retorna realment, quantes files i per què no respon a la seva pregunta. Escriu després les dues consultes correctes: la que dona la llista de mètodes i la que dona el nombre.
Exercici 3
Fent servir DISTINCT ON, obtén la comanda més recent de cada client que hagi comprat: client_id, id de la comanda, data_comanda i estat. Explica per què el resultat té 12 files i no 15, i quin paper hi juga l'ORDER BY.
Solucions
Solució 1
| pais | ciutat |
|---|---|
| França | Lió |
| França | París |
| Portugal | Lisboa |
| Portugal | Porto |
4 files. El raonament segueix l'ordre lògic d'execució:
FROM clients→ 15 files.WHERE pais <> 'Espanya'→ en queden 4 (els clients 7, 8, 9 i 10). Aquí no hi ha problema de nuls perquèpaisésNOT NULL; si admetés nuls, aquests clients s'haurien perdut silenciosament, com vas veure a 02-03.SELECT pais, ciutat→ projecta dues columnes d'aquestes 4 files.DISTINCT→ busca combinacions repetides... i no n'hi ha cap, perquè els quatre clients estrangers viuen en quatre ciutats diferents.
És a dir, en aquest cas concret DISTINCT no elimina res. Això no el fa inútil: garanteix que si demà es registra un segon client a Lisboa, l'informe continuarà sent correcte.
Solució 2
La consulta del company retorna les combinacions diferents de mètode de pagament i estat:
| metode_pagament | estat |
|---|---|
| targeta | lliurat |
| targeta | cancellat |
| targeta | enviat |
| targeta | pagat |
| transferencia | lliurat |
| transferencia | pagat |
| paypal | lliurat |
| paypal | enviat |
| contrareemborsament | lliurat |
| contrareemborsament | pendent |
10 files. targeta hi apareix quatre vegades, una per cada estat en què hi ha alguna comanda pagada amb targeta. No respon a "quants mètodes de pagament diferents hi ha" perquè DISTINCT deduplica la parella completa, i les parelles són diferents encara que comparteixin el mètode.
Les dues consultes correctes:
| metode_pagament |
|---|
| contrareemborsament |
| paypal |
| targeta |
| transferencia |
| metodes_usats |
|---|
| 4 |
La moralitat: cada columna que afegeixes al SELECT pot multiplicar les files del resultat, perquè debilita la condició d'igualtat que fa servir DISTINCT. Abans d'afegir una columna a un SELECT DISTINCT, pregunta't si continua responent a la teva pregunta.
Solució 3
SELECT DISTINCT ON (client_id)
client_id,
id,
data_comanda,
estat
FROM comandes
ORDER BY client_id, data_comanda DESC;| client_id | id | data_comanda | estat |
|---|---|---|---|
| 1 | 15 | 2025-12-02 | lliurat |
| 2 | 11 | 2025-09-09 | lliurat |
| 3 | 3 | 2025-04-02 | lliurat |
| 4 | 16 | 2025-12-19 | enviat |
| 5 | 18 | 2026-01-27 | pagat |
| 6 | 19 | 2026-02-09 | pagat |
| 7 | 17 | 2026-01-13 | enviat |
| 8 | 9 | 2025-07-15 | lliurat |
| 9 | 20 | 2026-02-21 | pendent |
| 10 | 12 | 2025-10-01 | lliurat |
| 11 | 13 | 2025-10-22 | lliurat |
| 12 | 14 | 2025-11-14 | lliurat |
12 files i no 15. El motiu és als buits deliberats del conjunt de dades: els clients 13, 14 i 15 no han fet cap comanda, així que no apareixen a la taula comandes i no hi ha res a agrupar per a ells. Una consulta sobre comandes només pot parlar de clients que han demanat; per llistar també els que no van comprar mai cal combinar les dues taules amb un LEFT JOIN, que és exactament el contingut de la lliçó 03-03.
El paper de l'ORDER BY és doble i tots dos són imprescindibles:
client_idprimer perquè és la columna delDISTINCT ON: PostgreSQL exigeix que coincideixin, ja que necessita les files de cada client juntes per quedar-se'n una.data_comanda DESCdesprés perquè determina quina de les files de cada client sobreviu: la primera del grup, és a dir, la de data més alta.
Si escrivissis ORDER BY client_id, data_comanda (ascendent), obtindries la primera comanda de cada client. I si ometessis la segona columna de l'ORDER BY, la fila triada dins de cada client seria la que el motor retornés primer, que pot canviar entre execucions.
Comprovació ràpida: la Lucía Martínez (client 1) té les comandes 1, 5 i 15, amb dates 2025-03-04, 2025-05-07 i 2025-12-02. N'ha sortit la 15, la més recent. Correcte.
Conclusió
Ja saps tractar els duplicats:
- Les files repetides no vénen de les dades, sinó de la projecció: en treure columnes, el que queda es repeteix. SQL treballa amb multiconjunts i no les elimina si no l'hi demanes.
DISTINCTs'escriu just després deSELECTi elimina files repetides comparant la combinació completa de columnes projectades, no només la primera.- S'aplica després de la projecció i abans d'
ORDER BY, d'on surt la restricció que tot el que ordenis ha de ser alSELECT. - Els
NULLes col·lapsen en una sola fila, per excepció a la regla general dels nuls. COUNT(DISTINCT columna)compta valors únics i és l'aplicació més habitual en anàlisi de dades; les agregacions completes arriben al mòdul 4.DISTINCT ON (...)és una extensió de PostgreSQL que retorna la primera fila de cada grup segons l'ORDER BY, i resol en tres línies el patró "la fila més recent / més cara de cada X". Fora de PostgreSQL es fa amb funcions de finestra (mòdul 10).DISTINCTcosta (ordenar o construir una taula hash) i, quan apareix per sorpresa, sol delatar una consulta mal plantejada més que resoldre un problema.
A la lliçó següent, Ordenar dades amb ORDER BY, deixaràs d'acceptar l'ordre que el motor tingui a bé donar-te. Veuràs com ordenar per una o diverses columnes, com es resolen els empats, com ordenar per àlies i per expressions calculades, on col·loca PostgreSQL els valors nuls (i per què MySQL els posa a l'altre extrem) i per què una lletra accentuada pot aparèixer on no esperes.
Curs de SQL
Mòdul 1: Introducció a SQL
- Què és SQL?
- Configurar el teu entorn SQL
- Sintaxi bàsica de SQL
- Entendre bases de dades i taules
- El model relacional: claus primàries i foranes
- La base de dades del curs: BotigaVerda
Mòdul 2: Consultes bàsiques de SQL
- Instrucció SELECT
- Àlies, expressions i columnes calculades
- Filtrar dades amb WHERE
- DISTINCT i eliminació de duplicats
- Ordenar dades amb ORDER BY
- Limitar resultats amb LIMIT
Mòdul 3: Treballar amb múltiples taules
- Operacions JOIN
- INNER JOIN
- LEFT JOIN
- RIGHT JOIN
- FULL OUTER JOIN
- SELF JOIN i CROSS JOIN
- Unions de conjunts: UNION, INTERSECT i EXCEPT
Mòdul 4: Filtratge avançat de dades
- Utilitzar LIKE per a coincidència de patrons
- Operadors IN i BETWEEN
- Valors NULL i IS NULL
- Funcions d'agregació: COUNT, SUM, AVG, MIN i MAX
- Agregar dades amb GROUP BY
- Clàusula HAVING
Mòdul 5: Manipulació de dades
- Crear taules i restriccions amb CREATE TABLE
- Instrucció INSERT
- Instrucció UPDATE
- Instrucció DELETE
- Instrucció UPSERT (MERGE)
- Modificar l'esquema: ALTER TABLE i migracions segures
Mòdul 6: Funcions avançades de SQL
- Funcions de cadena
- Funcions numèriques
- Funcions de data i hora
- Conversió de tipus i tractament dels NULL: CAST i COALESCE
- Expressions condicionals
Mòdul 7: Subconsultes i consultes imbricades
- Introducció a les subconsultes
- Subconsultes correlacionades
- EXISTS i NOT EXISTS
- Utilitzar subconsultes en les clàusules SELECT, FROM i WHERE
- Subconsultes o JOIN: quin triar
Mòdul 8: Índexs i optimització del rendiment
- Entendre els índexs
- Creació i gestió d'índexs
- Tipus d'índex i quan no indexar
- Tècniques d'optimització de consultes
- Anàlisi del rendiment de les consultes
Mòdul 9: Transaccions i concurrència
- Introducció a les transaccions
- Propietats ACID
- Instruccions de control de transaccions
- Nivells d'aïllament i anomalies de concurrència
- Gestió de la concurrència: bloquejos i interbloquejos
Mòdul 10: Temes avançats
- Vistes
- Expressions de taula comunes (CTE)
- Funcions de finestra
- Procediments emmagatzemats
- Disparadors (triggers)
- JSON i dades semiestructurades
Mòdul 11: SQL a la pràctica
- Casos d'ús al món real
- Bones pràctiques
- Seguretat: injecció SQL, permisos i rols
- SQL per a l'anàlisi de dades
- SQL en el desenvolupament web
