Aprendre SQL llegint és com aprendre a nedar mirant vídeos: necessari, però insuficient. Perquè aquest curs et serveixi de debò necessites un entorn on puguis escriure consultes, equivocar-te, veure el missatge d'error i tornar-ho a intentar. Aquesta lliçó et porta de la mà des de "no tinc res instal·lat" fins a "tinc PostgreSQL 16 funcionant, sé connectar-m'hi i he creat la base de dades botigaverda". Cobrirem la instal·lació a Linux, macOS i Windows, l'alternativa amb Docker (la que recomanem), una sortida d'emergència amb SQLite si no pots instal·lar res al teu equip, les ordres essencials del client psql i els clients gràfics més utilitzats.
Contingut
- Què necessites exactament
- Opció A (recomanada): PostgreSQL amb Docker
- Opció B: instal·lació nativa a Linux, macOS i Windows
- Opció C (mínima): SQLite
- Connectar-se amb
psqli les seves ordres bàsiques - Clients gràfics: pgAdmin, DBeaver i VS Code
- Crear la base de dades
botigaverdai un usuari propi - Verificar que tot funciona
- Errors habituals i consells
- Exercicis
- Conclusió
- Què necessites exactament
Per seguir el curs necessites tres peces:
| Peça | Què és | Recomanació del curs |
|---|---|---|
| El servidor | El procés que desa les dades i executa les consultes | PostgreSQL 16 |
| Un client de línia d'ordres | Per escriure consultes i veure resultats | psql (ve amb PostgreSQL) |
| Un client gràfic (opcional) | Per explorar taules còmodament | DBeaver o pgAdmin |
I has de decidir com instal·laràs el servidor. Aquestes són les tres vies, ordenades pel que recomanem:
graph TD
A[Pots instal·lar programari<br/>al teu equip?] -->|Sí| B[Tens Docker<br/>o el pots instal·lar?]
A -->|No| E[Opció C: SQLite<br/>o PostgreSQL al núvol]
B -->|Sí| C[Opció A: Docker<br/>RECOMANADA]
B -->|No| D[Opció B: instal·lació<br/>nativa del sistema]
| Opció | Avantatges | Inconvenients |
|---|---|---|
| A. Docker | Versió exacta i reproduïble; s'esborra sense deixar rastre; idèntica en els tres sistemes operatius | Requereix Docker instal·lat |
| B. Nativa | Arrenca amb el sistema; sense capa intermèdia | Depèn del sistema; desinstal·lar-la del tot és més empipador |
| C. SQLite | Zero instal·lació de servidor; un sol fitxer | Dialecte més limitat: no veuràs usuaris, tipus estrictes ni bona part dels mòduls 8, 9 i 10 |
- Opció A (recomanada): PostgreSQL amb Docker
Docker et permet aixecar PostgreSQL 16 en un contenidor aïllat, amb la mateixa versió exacta que fa servir el curs, sense tocar la resta del teu sistema.
2.1. Aixecar el contenidor
docker run --name pg-curs \
-e POSTGRES_PASSWORD=curs2026 \
-e POSTGRES_USER=postgres \
-e POSTGRES_DB=postgres \
-p 5432:5432 \
-v pgdata-curs:/var/lib/postgresql/data \
-d postgres:16Val la pena entendre cada opció, perquè les tornaràs a veure:
| Opció | Què fa |
|---|---|
--name pg-curs |
Dona un nom al contenidor per referir-t'hi després |
-e POSTGRES_PASSWORD=... |
Contrasenya del superusuari. Obligatòria: sense ella el contenidor no arrenca |
-e POSTGRES_USER=postgres |
Nom del superusuari (per defecte ja és postgres) |
-p 5432:5432 |
Publica el port del contenidor a la teva màquina, perquè els clients externs s'hi puguin connectar |
-v pgdata-curs:/var/lib/postgresql/data |
Volum persistent: sense això perdries totes les dades en esborrar el contenidor |
-d |
Executa en segon pla (detached) |
postgres:16 |
Imatge oficial, versió 16 |
2.2. Comprovar que està en marxa
Als registres has de veure una línia semblant a database system is ready to accept connections.
2.3. Cicle de vida del contenidor
docker stop pg-curs # Apagar (les dades continuen allà)
docker start pg-curs # Tornar a encendre
docker rm -f pg-curs # Esborrar el contenidor (el volum pgdata-curs sobreviu)
docker volume rm pgdata-curs # Esborrar TAMBÉ les dades. Compte amb això.Nota: si el port 5432 ja està ocupat per una altra instal·lació de PostgreSQL, canvia la publicació a
-p 5433:5432i fes servir-p 5433en connectar-t'hi.
- Opció B: instal·lació nativa a Linux, macOS i Windows
| Sistema | Ordres d'instal·lació | Com s'arrenca | Notes |
|---|---|---|---|
| Debian / Ubuntu | sudo apt updatesudo apt install postgresql-16 postgresql-client-16 |
sudo systemctl start postgresqlsudo systemctl enable postgresql |
Es crea l'usuari del sistema postgres; s'hi entra amb sudo -u postgres psql |
| Fedora / RHEL | sudo dnf install postgresql16-server postgresql16sudo /usr/pgsql-16/bin/postgresql-16-setup initdb |
sudo systemctl enable --now postgresql-16 |
Cal inicialitzar el clúster explícitament |
| Arch Linux | sudo pacman -S postgresqlsudo -u postgres initdb -D /var/lib/postgres/data |
sudo systemctl enable --now postgresql |
|
| macOS (Homebrew) | brew install postgresql@16 |
brew services start postgresql@16 |
Crea una base de dades amb el teu nom d'usuari |
| macOS (Postgres.app) | Descarregar de postgresapp.com i arrossegar a Aplicacions | Botó "Start" | La manera més simple al Mac; cal afegir el binari al PATH |
| Windows (instal·lador EDB) | Descarregar l'instal·lador d'enterprisedb.com i seguir l'assistent | Servei de Windows, arrenca sol | Inclou pgAdmin 4 i l'Stack Builder |
| Windows (winget) | winget install PostgreSQL.PostgreSQL.16 |
Servei de Windows | Via ràpida sense assistent gràfic |
Detalls que solen donar problemes:
- Linux/Debian: després d'instal·lar, l'accés local es fa per peer authentication. La manera correcta d'entrar-hi el primer cop és
sudo -u postgres psql, nopsqla seques. - macOS amb Homebrew: si
psqlno es troba, afegeix la ruta alPATH:echo 'export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH"' >> ~/.zshrc source ~/.zshrc - Windows: l'instal·lador no sempre afegeix
psqlalPATH. Si en obrir el PowerShell et diu que no reconeix l'ordre, afegeix a màC:\Program Files\PostgreSQL\16\bina la variable d'entornPath, o fes servir l'accés directe "SQL Shell (psql)" del menú Inici.
- Opció C (mínima): SQLite
Si treballes en un equip on no pots instal·lar serveis, SQLite et permetrà seguir bona part del curs. Una base de dades SQLite és un únic fitxer i no hi ha cap servidor per arrencar.
# Linux (Debian/Ubuntu)
sudo apt install sqlite3
# macOS: ja ve instal·lat
sqlite3 --version
# Windows (winget)
winget install SQLite.SQLiteCrear una base de dades i entrar-hi és el mateix:
Les seves ordres de client comencen per punt en comptes de barra invertida:
| Tasca | psql (PostgreSQL) | sqlite3 |
|---|---|---|
| Llistar taules | \dt |
.tables |
| Descriure una taula | \d productes |
.schema productes |
| Sortir | \q |
.quit |
| Executar un fitxer | \i fitxer.sql |
.read fitxer.sql |
| Ajuda | \? |
.help |
Limitacions honestes de SQLite per a aquest curs: no té usuaris ni permisos (mòdul 11), els seus tipus són dinàmics i molt permissius (mòduls 1 i 5), no admet
RIGHT/FULL OUTER JOINen versions anteriors a la 3.39, el seuEXPLAINés diferent (mòdul 8) i no té procediments emmagatzemats ni triggers equivalents (mòdul 10). Fes-lo servir com a últim recurs; si en algun moment pots passar-te a PostgreSQL, fes-ho.
- Connectar-se amb
psql i les seves ordres bàsiques
psql i les seves ordres bàsiquespsql és el client oficial de línia d'ordres. És l'eina que farem servir a les explicacions perquè és ràpida, sempre està disponible i mostra els errors tal com els produeix el servidor.
5.1. Connectar-se
# Instal·lació nativa a Linux, el primer cop
sudo -u postgres psql
# Connexió explícita indicant servidor, port, usuari i base de dades
psql -h localhost -p 5432 -U postgres -d postgres
# Si fas servir Docker, pots entrar directament al contenidor
docker exec -it pg-curs psql -U postgres -d postgres
# També val una cadena de connexió completa (URI)
psql "postgresql://postgres:curs2026@localhost:5432/postgres"Les opcions es repeteixen en gairebé totes les eines de PostgreSQL:
| Opció | Significat | Valor habitual |
|---|---|---|
-h |
Host del servidor | localhost |
-p |
Port | 5432 |
-U |
Usuari | postgres |
-d |
Base de dades a la qual connectar-se | botigaverda |
-f |
Executar un fitxer .sql i sortir |
-f botigaverda.sql |
-c |
Executar una sola sentència i sortir | -c "SELECT version();" |
Quan hi ets a dins, el símbol del sistema t'informa de l'estat:
postgres=# -- connectat a la BD "postgres" com a superusuari botigaverda=> -- connectat a "botigaverda" com a usuari normal botigaverda-# -- sentència SENSE acabar: falta el punt i coma botigaverda'# -- tens una cometa simple oberta
Aquest tercer símbol (-#) és el que més desconcerta al principi: significa que psql està esperant que tanquis la sentència amb ;.
5.2. Les metaordres imprescindibles
Les ordres que comencen per \ no són SQL: les interpreta el client mateix, i per això no porten punt i coma.
| Ordre | Què fa |
|---|---|
\l |
Llista totes les bases de dades del servidor |
\c botigaverda |
Es connecta a la base de dades botigaverda |
\dt |
Llista les taules de l'esquema actual |
\d productes |
Descriu la taula productes: columnes, tipus, claus i índexs |
\dn |
Llista els esquemes |
\du |
Llista els usuaris i rols |
\df |
Llista les funcions |
\i fitxer.sql |
Executa un fitxer SQL |
\x |
Alterna la vista expandida (una columna per línia): salva la vida amb taules amples |
\timing |
Activa/desactiva el temps d'execució de cada consulta |
\e |
Obre l'última consulta al teu editor de text |
\? |
Ajuda de les metaordres |
\h SELECT |
Ajuda de sintaxi d'una sentència SQL concreta |
\q |
Sortir |
Exemple de sessió típica:
postgres=# \l postgres=# \c botigaverda You are now connected to database "botigaverda" as user "postgres". botigaverda=# \dt botigaverda=# \d productes botigaverda=# \timing Timing is on. botigaverda=# \q
- Clients gràfics: pgAdmin, DBeaver i VS Code
Un client gràfic no substitueix psql, però accelera moltíssim l'exploració d'un esquema desconegut.
| Client | Motors que admet | Punt fort | Punt feble | Ideal per a |
|---|---|---|---|---|
| pgAdmin 4 | Només PostgreSQL | Administració completa del servidor; ve amb l'instal·lador de Windows | Interfície web pesada; poc àgil per escriure consultes | Administrar PostgreSQL a fons |
| DBeaver Community | PostgreSQL, MySQL, SQLite, Oracle, SQL Server i desenes més | Un sol client per a tot; bon editor amb autocompletat i diagrames ER | Consumeix bastant memòria (és Java) | La recomanació general del curs |
| Extensió SQL de VS Code | PostgreSQL, MySQL, SQLite (segons extensió) | Consultes dins de l'editor on ja programes; fitxers .sql versionables a Git |
Menys funcions d'administració | Qui ja viu al VS Code |
| TablePlus / DataGrip | Múltiples | Molt polits i ràpids | De pagament | Ús professional diari |
Dades de connexió que et demanarà qualsevol d'ells (amb la configuració de Docker de la secció 2):
| Camp | Valor |
|---|---|
| Host | localhost |
| Port | 5432 |
| Base de dades | botigaverda |
| Usuari | postgres (o curs_sql, vegeu la secció 7) |
| Contrasenya | curs2026 |
- Crear la base de dades
botigaverda i un usuari propi
botigaverda i un usuari propiPrepararem l'espai de treball del curs. Connecta't primer com a superusuari:
I executa:
-- 1. Crear un usuari propi per al curs, en comptes de treballar com a superusuari
CREATE USER curs_sql WITH PASSWORD 'curs2026';
-- 2. Crear la base de dades del curs, amb aquest usuari com a propietari
CREATE DATABASE botigaverda
OWNER curs_sql
ENCODING 'UTF8'
TEMPLATE template0
LC_COLLATE 'ca_ES.UTF-8'
LC_CTYPE 'ca_ES.UTF-8';Què fa cada part:
CREATE USERcrea un rol amb capacitat d'iniciar sessió. Treballar com a superusuari cada dia és un mal costum: unDROPaccidental no tindria cap barrera.OWNER curs_sqlfa que aquest usuari sigui l'amo de la base de dades i pugui crear-hi taules sense permisos addicionals.ENCODING 'UTF8'garanteix que els accents i laçde les nostres dades es desin correctament.LC_COLLATEdefineix l'ordre alfabètic de l'idioma: amb la configuració catalana,ORDER BYcol·locarà "àlber" abans de "bosc", com esperaries.
Si el
LC_COLLATEet dona error: a la imatge Docker de PostgreSQL pot ser que el locale català no estigui generat. En aquest cas, crea la base sense aquestes dues clàusules:CREATE DATABASE botigaverda OWNER curs_sql ENCODING 'UTF8';No afecta res del curs tret de petits matisos d'ordenació alfabètica.
Ara connecta't a la base nova amb el teu usuari:
I concedeix permisos sobre l'esquema public (necessari des de PostgreSQL 15, que va endurir els permisos per defecte). Això s'executa com a superusuari:
- Verificar que tot funciona
La comprovació canònica és demanar-li al servidor la seva versió:
Resultat esperat (el text exacte variarà segons el teu sistema):
| version |
|---|
| PostgreSQL 16.4 on x86_64-pc-linux-gnu, compiled by gcc 12.2.0, 64-bit |
Un parell de verificacions més, útils per confirmar que ets on creus ser:
| current_database | current_user | now |
|---|---|---|
| botigaverda | curs_sql | 2026-02-25 10:14:07.412+01 |
I una prova ràpida que pots crear objectes a la base:
CREATE TABLE prova (id INTEGER, contingut TEXT);
INSERT INTO prova VALUES (1, 'Hola BotigaVerda');
SELECT * FROM prova;
DROP TABLE prova;| id | contingut |
|---|---|
| 1 | Hola BotigaVerda |
Si les quatre sentències s'executen sense error, el teu entorn està a punt. Amb DROP TABLE prova; deixes la base neta per a l'script real, que carregaràs a la lliçó 01-06.
Llista de comprovació
| Comprovació | Ordre | Resultat esperat |
|---|---|---|
| El servidor respon | SELECT version(); |
Una línia amb "PostgreSQL 16" |
| La base existeix | \l |
Apareix botigaverda a la llista |
| Hi estàs connectat | SELECT current_database(); |
botigaverda |
| Pots crear taules | CREATE TABLE prova (...) |
CREATE TABLE |
| El client gràfic connecta | Provar la connexió a DBeaver/pgAdmin | Connexió correcta |
Errors habituals i consells
psql: error: connection to server ... failed: Connection refused. El servidor no està arrencat o el port és un altre. Amb Docker, comprovadocker ps; amb instal·lació nativa,sudo systemctl status postgresql.FATAL: password authentication failed for user "postgres". Contrasenya incorrecta, o estàs fent servir la d'un altre entorn. A Docker, la contrasenya és la que vas passar aPOSTGRES_PASSWORDel primer cop que es va crear el volum: canviar-la en undocker runposterior no té cap efecte si el volum ja existeix.FATAL: role "el_teu_usuari" does not exist. A Linux,psqlintenta connectar-se amb el teu usuari del sistema. Fes servir-U postgresexplícitament o entra ambsudo -u postgres psql.FATAL: database "botigaverda" does not exist. Encara no l'has creada, o la vas crear en un servidor diferent del que estàs consultant.- Oblidar el punt i coma. Si el símbol del sistema passa de
=#a-#,psqlestà esperant el;. Escriu-lo i prem Retorn. - Perdre les dades en recrear el contenidor. Sense
-vno hi ha volum, i esborrar el contenidor esborra la base sencera. És l'error més dolorós de Docker. - Consell: desa les teves consultes en fitxers
.sql. Crea una carpetacurs-sql/amb un fitxer per mòdul. Els podràs executar amb\ii portaràs un registre del teu progrés. - Consell: activa
\timingdes del primer dia. T'acostumaràs a mirar quant triga cada consulta, una cosa que et sortirà natural quan arribis al mòdul 8. - Consell: fes servir
\xamb taules amples. Quan una fila no cap a la pantalla i el resultat és il·legible,\xel converteix en una llista vertical de camps.
Exercicis
Exercici 1
Aixeca PostgreSQL 16 amb Docker al port 5433 en comptes del 5432 (útil si ja tens un altre PostgreSQL a la teva màquina), amb el nom de contenidor pg-botigaverda i un volum anomenat bv-data. Després, connecta't amb psql i comprova la versió del servidor.
Exercici 2
Des de psql, i sense sortir del client, respon a aquestes tres preguntes fent servir metaordres (no SQL):
- Quines bases de dades hi ha al teu servidor?
- Quins usuaris/rols hi ha definits?
- Quina és la sintaxi completa de la sentència
CREATE DATABASE?
Exercici 3
Crea una base de dades anomenada proves_sql propietat de l'usuari curs_sql, connecta-t'hi, crea una taula notes(id, contingut), insereix-hi dues files, consulta-les i finalment elimina la base de dades sencera.
Solucions
Solució 1
docker run --name pg-botigaverda \
-e POSTGRES_PASSWORD=curs2026 \
-p 5433:5432 \
-v bv-data:/var/lib/postgresql/data \
-d postgres:16El detall clau és -p 5433:5432: el número de l'esquerra és el port de la teva màquina i el de la dreta el del contenidor (que sempre és 5432, perquè dins del contenidor PostgreSQL escolta allà). Per connectar-t'hi:
Solució 2
\l (de list) mostra bases de dades amb el seu propietari i codificació; \du (display users) mostra rols i els seus atributs; \h dona l'ajuda de sintaxi SQL, mentre que \? dona la de les metaordres. Recorda: cap no porta punt i coma, perquè no són SQL.
Solució 3
CREATE TABLE notes (id INTEGER, contingut TEXT);
INSERT INTO notes VALUES (1, 'Primera nota'), (2, 'Segona nota');
SELECT * FROM notes;| id | contingut |
|---|---|
| 1 | Primera nota |
| 2 | Segona nota |
Per esborrar la base de dades no hi pots estar connectat, així que primer torna a postgres:
Si intentes el DROP estant-hi a dins, PostgreSQL respon ERROR: cannot drop the currently open database. És un error molt freqüent i la solució sempre és la mateixa: canviar de base de dades abans.
Conclusió
Ja tens un entorn de treball real:
- Coneixes les tres vies per tenir PostgreSQL 16: Docker (reproduïble i recomanada), instal·lació nativa per sistema operatiu i SQLite com a últim recurs.
- Coneixes el client
psql, les seves opcions de connexió (-h,-p,-U,-d,-f,-c) i les seves metaordres clau (\l,\c,\dt,\d,\x,\timing,\?,\q). - Pots triar un client gràfic amb criteri: DBeaver com a opció general, pgAdmin per administrar, VS Code si ja hi treballes.
- Has creat la base de dades
botigaverdai l'usuaricurs_sql, i has verificat la instal·lació ambSELECT version();.
A la lliçó següent, Sintaxi bàsica de SQL, deixarem d'instal·lar i començarem a escriure: veuràs com està construïda una sentència SQL per dins (paraules clau, identificadors, literals, operadors), quin paper hi juga el punt i coma, com tracta PostgreSQL les majúscules, com comentar el teu codi, quines convencions de format fan servir els professionals i —molt important— com llegir un missatge d'error per saber exactament on t'has equivocat.
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
