Aprender SQL leyendo es como aprender a nadar viendo vídeos: necesario, pero insuficiente. Para que este curso te sirva de verdad necesitas un entorno donde puedas escribir consultas, equivocarte, ver el mensaje de error y volver a intentarlo. Esta lección te lleva de la mano desde "no tengo nada instalado" hasta "tengo PostgreSQL 16 funcionando, sé conectarme y he creado la base de datos tiendaverde". Cubriremos la instalación en Linux, macOS y Windows, la alternativa con Docker (la que recomendamos), una salida de emergencia con SQLite si no puedes instalar nada en tu equipo, los comandos esenciales del cliente psql y los clientes gráficos más usados.
Contenido
- Qué necesitas exactamente
- Opción A (recomendada): PostgreSQL con Docker
- Opción B: instalación nativa en Linux, macOS y Windows
- Opción C (mínima): SQLite
- Conectarse con
psqly sus comandos básicos - Clientes gráficos: pgAdmin, DBeaver y VS Code
- Crear la base de datos
tiendaverdey un usuario propio - Verificar que todo funciona
- Errores Comunes y Consejos
- Ejercicios
- Conclusión
- Qué necesitas exactamente
Para seguir el curso necesitas tres piezas:
| Pieza | Qué es | Recomendación del curso |
|---|---|---|
| El servidor | El proceso que guarda los datos y ejecuta las consultas | PostgreSQL 16 |
| Un cliente de línea de comandos | Para escribir consultas y ver resultados | psql (viene con PostgreSQL) |
| Un cliente gráfico (opcional) | Para explorar tablas cómodamente | DBeaver o pgAdmin |
Y necesitas decidir cómo vas a instalar el servidor. Estas son las tres vías, ordenadas por lo que recomendamos:
graph TD
A[¿Puedes instalar software<br/>en tu equipo?] -->|Sí| B[¿Tienes Docker<br/>o puedes instalarlo?]
A -->|No| E[Opción C: SQLite<br/>o PostgreSQL en la nube]
B -->|Sí| C[Opción A: Docker<br/>RECOMENDADA]
B -->|No| D[Opción B: instalación<br/>nativa del sistema]
| Opción | Ventajas | Inconvenientes |
|---|---|---|
| A. Docker | Versión exacta y reproducible; se borra sin dejar rastro; idéntica en los tres sistemas operativos | Requiere Docker instalado |
| B. Nativa | Arranca con el sistema; sin capa intermedia | Depende del sistema; desinstalar limpio es más engorroso |
| C. SQLite | Cero instalación de servidor; un solo fichero | Dialecto más limitado: no verás usuarios, tipos estrictos ni buena parte de los módulos 8, 9 y 10 |
- Opción A (recomendada): PostgreSQL con Docker
Docker te permite levantar PostgreSQL 16 en un contenedor aislado, con la misma versión exacta que usa el curso, sin tocar el resto de tu sistema.
2.1. Levantar el contenedor
docker run --name pg-curso \
-e POSTGRES_PASSWORD=curso2026 \
-e POSTGRES_USER=postgres \
-e POSTGRES_DB=postgres \
-p 5432:5432 \
-v pgdata-curso:/var/lib/postgresql/data \
-d postgres:16Vale la pena entender cada opción, porque las volverás a ver:
| Opción | Qué hace |
|---|---|
--name pg-curso |
Da un nombre al contenedor para referirte a él después |
-e POSTGRES_PASSWORD=... |
Contraseña del superusuario. Obligatoria: sin ella el contenedor no arranca |
-e POSTGRES_USER=postgres |
Nombre del superusuario (por defecto ya es postgres) |
-p 5432:5432 |
Publica el puerto del contenedor en tu máquina, para que clientes externos puedan conectarse |
-v pgdata-curso:/var/lib/postgresql/data |
Volumen persistente: sin esto perderías todos los datos al borrar el contenedor |
-d |
Ejecuta en segundo plano (detached) |
postgres:16 |
Imagen oficial, versión 16 |
2.2. Comprobar que está en marcha
En los registros debes ver una línea similar a database system is ready to accept connections.
2.3. Ciclo de vida del contenedor
docker stop pg-curso # Apagar (los datos siguen ahí)
docker start pg-curso # Volver a encender
docker rm -f pg-curso # Borrar el contenedor (el volumen pgdata-curso sobrevive)
docker volume rm pgdata-curso # Borrar TAMBIÉN los datos. Cuidado con esto.Nota: si el puerto 5432 ya está ocupado por otra instalación de PostgreSQL, cambia la publicación a
-p 5433:5432y usa-p 5433al conectarte.
- Opción B: instalación nativa en Linux, macOS y Windows
| Sistema | Comandos de instalación | Cómo se arranca | Notas |
|---|---|---|---|
| Debian / Ubuntu | sudo apt updatesudo apt install postgresql-16 postgresql-client-16 |
sudo systemctl start postgresqlsudo systemctl enable postgresql |
Se crea el usuario del sistema postgres; se entra con 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 |
Requiere inicializar el clúster explícitamente |
| 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 datos con tu nombre de usuario |
| macOS (Postgres.app) | Descargar de postgresapp.com y arrastrar a Aplicaciones | Botón "Start" | La forma más simple en Mac; hay que añadir el binario al PATH |
| Windows (instalador EDB) | Descargar el instalador de enterprisedb.com y seguir el asistente | Servicio de Windows, arranca solo | Incluye pgAdmin 4 y el Stack Builder |
| Windows (winget) | winget install PostgreSQL.PostgreSQL.16 |
Servicio de Windows | Vía rápida sin asistente gráfico |
Detalles que suelen dar problemas:
- Linux/Debian: tras instalar, el acceso local se hace por peer authentication. La forma correcta de entrar la primera vez es
sudo -u postgres psql, nopsqla secas. - macOS con Homebrew: si
psqlno se encuentra, añade la ruta alPATH:echo 'export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH"' >> ~/.zshrc source ~/.zshrc - Windows: el instalador no siempre añade
psqlalPATH. Si al abrir PowerShell te dice que no reconoce el comando, añade a manoC:\Program Files\PostgreSQL\16\bina la variable de entornoPath, o usa el acceso directo "SQL Shell (psql)" del menú Inicio.
- Opción C (mínima): SQLite
Si trabajas en un equipo donde no puedes instalar servicios, SQLite te permitirá seguir buena parte del curso. Una base de datos SQLite es un único fichero y no hay servidor que arrancar.
# Linux (Debian/Ubuntu)
sudo apt install sqlite3
# macOS: ya viene instalado
sqlite3 --version
# Windows (winget)
winget install SQLite.SQLiteCrear una base de datos y entrar en ella es lo mismo:
Sus comandos de cliente empiezan por punto en lugar de barra invertida:
| Tarea | psql (PostgreSQL) | sqlite3 |
|---|---|---|
| Listar tablas | \dt |
.tables |
| Describir una tabla | \d productos |
.schema productos |
| Salir | \q |
.quit |
| Ejecutar un fichero | \i fichero.sql |
.read fichero.sql |
| Ayuda | \? |
.help |
Limitaciones honestas de SQLite para este curso: no tiene usuarios ni permisos (módulo 11), sus tipos son dinámicos y muy permisivos (módulo 1 y 5), no soporta
RIGHT/FULL OUTER JOINen versiones anteriores a la 3.39, suEXPLAINes distinto (módulo 8) y no tiene procedimientos almacenados ni triggers equivalentes (módulo 10). Úsalo como último recurso; si en algún momento puedes pasarte a PostgreSQL, hazlo.
- Conectarse con
psql y sus comandos básicos
psql y sus comandos básicospsql es el cliente oficial de línea de comandos. Es la herramienta que usaremos en las explicaciones porque es rápida, está siempre disponible y muestra los errores tal cual los produce el servidor.
5.1. Conectarse
# Instalación nativa en Linux, la primera vez
sudo -u postgres psql
# Conexión explícita indicando servidor, puerto, usuario y base de datos
psql -h localhost -p 5432 -U postgres -d postgres
# Si usas Docker, puedes entrar directamente al contenedor
docker exec -it pg-curso psql -U postgres -d postgres
# También vale una cadena de conexión completa (URI)
psql "postgresql://postgres:curso2026@localhost:5432/postgres"Las opciones se repiten en casi todas las herramientas PostgreSQL:
| Opción | Significado | Valor habitual |
|---|---|---|
-h |
Host del servidor | localhost |
-p |
Puerto | 5432 |
-U |
Usuario | postgres |
-d |
Base de datos a la que conectarse | tiendaverde |
-f |
Ejecutar un fichero .sql y salir |
-f tiendaverde.sql |
-c |
Ejecutar una sola sentencia y salir | -c "SELECT version();" |
Cuando estás dentro, el símbolo del sistema te informa del estado:
postgres=# -- conectado a la BD "postgres" como superusuario tiendaverde=> -- conectado a "tiendaverde" como usuario normal tiendaverde-# -- sentencia SIN terminar: falta el punto y coma tiendaverde'# -- tienes una comilla simple abierta
Ese tercer símbolo (-#) es el que más desconcierta al principio: significa que psql está esperando a que cierres la sentencia con ;.
5.2. Los metacomandos imprescindibles
Los comandos que empiezan por \ no son SQL: los interpreta el propio cliente, y por eso no llevan punto y coma.
| Comando | Qué hace |
|---|---|
\l |
Lista todas las bases de datos del servidor |
\c tiendaverde |
Se conecta a la base de datos tiendaverde |
\dt |
Lista las tablas del esquema actual |
\d productos |
Describe la tabla productos: columnas, tipos, claves e índices |
\dn |
Lista los esquemas |
\du |
Lista los usuarios y roles |
\df |
Lista las funciones |
\i fichero.sql |
Ejecuta un fichero SQL |
\x |
Alterna la vista expandida (una columna por línea): salva la vida con tablas anchas |
\timing |
Activa/desactiva el tiempo de ejecución de cada consulta |
\e |
Abre la última consulta en tu editor de texto |
\? |
Ayuda de los metacomandos |
\h SELECT |
Ayuda de sintaxis de una sentencia SQL concreta |
\q |
Salir |
Ejemplo de sesión típica:
postgres=# \l postgres=# \c tiendaverde You are now connected to database "tiendaverde" as user "postgres". tiendaverde=# \dt tiendaverde=# \d productos tiendaverde=# \timing Timing is on. tiendaverde=# \q
- Clientes gráficos: pgAdmin, DBeaver y VS Code
Un cliente gráfico no sustituye a psql, pero acelera muchísimo la exploración de un esquema desconocido.
| Cliente | Motores que soporta | Punto fuerte | Punto débil | Ideal para |
|---|---|---|---|---|
| pgAdmin 4 | Solo PostgreSQL | Administración completa del servidor; viene con el instalador de Windows | Interfaz web pesada; poco ágil para escribir consultas | Administrar PostgreSQL a fondo |
| DBeaver Community | PostgreSQL, MySQL, SQLite, Oracle, SQL Server y decenas más | Un solo cliente para todo; buen editor con autocompletado y diagramas ER | Consume bastante memoria (es Java) | La recomendación general del curso |
| Extensión SQL de VS Code | PostgreSQL, MySQL, SQLite (según extensión) | Consultas dentro del editor donde ya programas; ficheros .sql versionables en Git |
Menos funciones de administración | Quien ya vive en VS Code |
| TablePlus / DataGrip | Múltiples | Muy pulidos y rápidos | De pago | Uso profesional diario |
Datos de conexión que te pedirá cualquiera de ellos (con la configuración de Docker de la sección 2):
| Campo | Valor |
|---|---|
| Host | localhost |
| Puerto | 5432 |
| Base de datos | tiendaverde |
| Usuario | postgres (o curso_sql, ver sección 7) |
| Contraseña | curso2026 |
- Crear la base de datos
tiendaverde y un usuario propio
tiendaverde y un usuario propioVamos a preparar el espacio de trabajo del curso. Conéctate primero como superusuario:
Y ejecuta:
-- 1. Crear un usuario propio para el curso, en lugar de trabajar como superusuario
CREATE USER curso_sql WITH PASSWORD 'curso2026';
-- 2. Crear la base de datos del curso, con ese usuario como propietario
CREATE DATABASE tiendaverde
OWNER curso_sql
ENCODING 'UTF8'
TEMPLATE template0
LC_COLLATE 'es_ES.UTF-8'
LC_CTYPE 'es_ES.UTF-8';Qué hace cada parte:
CREATE USERcrea un rol con capacidad de iniciar sesión. Trabajar como superusuario a diario es una mala costumbre: unDROPaccidental no tendría ninguna barrera.OWNER curso_sqlhace que ese usuario sea el dueño de la base de datos y pueda crear tablas dentro sin permisos adicionales.ENCODING 'UTF8'garantiza que las tildes y lañde nuestros datos se guarden correctamente.LC_COLLATEdefine el orden alfabético del idioma: con la configuración española,ORDER BYcolocará "álamo" antes de "bosque", como esperarías.
Si te da error el
LC_COLLATE: en la imagen Docker de PostgreSQL puede que el locale español no esté generado. En ese caso, crea la base sin esas dos cláusulas:CREATE DATABASE tiendaverde OWNER curso_sql ENCODING 'UTF8';No afecta a nada del curso salvo a pequeños matices de ordenación alfabética.
Ahora conéctate a la base nueva con tu usuario:
Y concede permisos sobre el esquema public (necesario desde PostgreSQL 15, que endureció los permisos por defecto). Esto se ejecuta como superusuario:
- Verificar que todo funciona
La comprobación canónica es pedirle al servidor su versión:
Resultado esperado (el texto exacto variará según tu sistema):
| version |
|---|
| PostgreSQL 16.4 on x86_64-pc-linux-gnu, compiled by gcc 12.2.0, 64-bit |
Un par de verificaciones más, útiles para confirmar que estás donde crees estar:
| current_database | current_user | now |
|---|---|---|
| tiendaverde | curso_sql | 2026-02-25 10:14:07.412+01 |
Y una prueba rápida de que puedes crear objetos en la base:
CREATE TABLE prueba (id INTEGER, texto TEXT);
INSERT INTO prueba VALUES (1, 'Hola TiendaVerde');
SELECT * FROM prueba;
DROP TABLE prueba;| id | texto |
|---|---|
| 1 | Hola TiendaVerde |
Si las cuatro sentencias se ejecutan sin error, tu entorno está listo. Con DROP TABLE prueba; dejas la base limpia para el script real, que cargarás en la lección 01-06.
Lista de comprobación
| Comprobación | Comando | Resultado esperado |
|---|---|---|
| El servidor responde | SELECT version(); |
Una línea con "PostgreSQL 16" |
| La base existe | \l |
Aparece tiendaverde en la lista |
| Estás conectado a ella | SELECT current_database(); |
tiendaverde |
| Puedes crear tablas | CREATE TABLE prueba (...) |
CREATE TABLE |
| El cliente gráfico conecta | Probar la conexión en DBeaver/pgAdmin | Conexión correcta |
Errores Comunes y Consejos
psql: error: connection to server ... failed: Connection refused. El servidor no está arrancado o el puerto es otro. Con Docker, compruebadocker ps; con instalación nativa,sudo systemctl status postgresql.FATAL: password authentication failed for user "postgres". Contraseña incorrecta, o estás usando la de otro entorno. En Docker, la contraseña es la que pasaste enPOSTGRES_PASSWORDla primera vez que se creó el volumen: cambiarla en undocker runposterior no tiene efecto si el volumen ya existe.FATAL: role "tu_usuario" does not exist. En Linux,psqlintenta conectarse con tu usuario del sistema. Usa-U postgresexplícitamente o entra consudo -u postgres psql.FATAL: database "tiendaverde" does not exist. Todavía no la has creado, o la creaste en otro servidor distinto del que estás consultando.- Olvidar el punto y coma. Si el símbolo del sistema pasa de
=#a-#,psqlestá esperando el;. Escríbelo y pulsa Intro. - Perder los datos al recrear el contenedor. Sin
-vno hay volumen, y borrar el contenedor borra la base entera. Es el error más doloroso de Docker. - Consejo: guarda tus consultas en ficheros
.sql. Crea una carpetacurso-sql/con un fichero por módulo. Podrás ejecutarlos con\iy llevarás un registro de tu progreso. - Consejo: activa
\timingdesde el primer día. Te acostumbrarás a mirar cuánto tarda cada consulta, algo que te será natural cuando llegues al módulo 8. - Consejo: usa
\xcon tablas anchas. Cuando una fila no cabe en pantalla y el resultado es ilegible,\xlo convierte en una lista vertical de campos.
Ejercicios
Ejercicio 1
Levanta PostgreSQL 16 con Docker en el puerto 5433 en lugar del 5432 (útil si ya tienes otro PostgreSQL en tu máquina), con el nombre de contenedor pg-tiendaverde y un volumen llamado tv-data. Después, conéctate con psql y comprueba la versión del servidor.
Ejercicio 2
Desde psql, y sin salir del cliente, responde a estas tres preguntas usando metacomandos (no SQL):
- ¿Qué bases de datos existen en tu servidor?
- ¿Qué usuarios/roles hay definidos?
- ¿Cuál es la sintaxis completa de la sentencia
CREATE DATABASE?
Ejercicio 3
Crea una base de datos llamada pruebas_sql propiedad del usuario curso_sql, conéctate a ella, crea una tabla notas(id, texto), inserta dos filas, consúltalas y finalmente elimina la base de datos entera.
Soluciones
Solución 1
docker run --name pg-tiendaverde \
-e POSTGRES_PASSWORD=curso2026 \
-p 5433:5432 \
-v tv-data:/var/lib/postgresql/data \
-d postgres:16El detalle clave es -p 5433:5432: el número de la izquierda es el puerto de tu máquina y el de la derecha el del contenedor (que siempre es 5432, porque dentro del contenedor PostgreSQL escucha ahí). Para conectarte:
Solución 2
\l (de list) muestra bases de datos con su propietario y codificación; \du (display users) muestra roles y sus atributos; \h da la ayuda de sintaxis SQL, mientras que \? da la de los metacomandos. Recuerda: ninguno lleva punto y coma, porque no son SQL.
Solución 3
CREATE TABLE notas (id INTEGER, texto TEXT);
INSERT INTO notas VALUES (1, 'Primera nota'), (2, 'Segunda nota');
SELECT * FROM notas;| id | texto |
|---|---|
| 1 | Primera nota |
| 2 | Segunda nota |
Para borrar la base de datos no puedes estar conectado a ella, así que primero vuelve a postgres:
Si intentas el DROP estando dentro, PostgreSQL responde ERROR: cannot drop the currently open database. Es un error muy frecuente y la solución siempre es la misma: cambiar de base de datos antes.
Conclusión
Ya tienes un entorno de trabajo real:
- Sabes las tres vías para tener PostgreSQL 16: Docker (reproducible y recomendada), instalación nativa por sistema operativo y SQLite como último recurso.
- Conoces el cliente
psql, sus opciones de conexión (-h,-p,-U,-d,-f,-c) y sus metacomandos clave (\l,\c,\dt,\d,\x,\timing,\?,\q). - Puedes elegir un cliente gráfico con criterio: DBeaver como opción general, pgAdmin para administrar, VS Code si ya trabajas ahí.
- Has creado la base de datos
tiendaverdey el usuariocurso_sql, y has verificado la instalación conSELECT version();.
En la siguiente lección, Sintaxis básica de SQL, dejaremos de instalar y empezaremos a escribir: verás cómo está construida una sentencia SQL por dentro (palabras clave, identificadores, literales, operadores), qué papel juega el punto y coma, cómo trata PostgreSQL las mayúsculas, cómo comentar tu código, qué convenciones de formato usan los profesionales y —muy importante— cómo leer un mensaje de error para saber exactamente dónde te has equivocado.
Curso de SQL
Módulo 1: Introducción a SQL
- ¿Qué es SQL?
- Configurando tu entorno SQL
- Sintaxis básica de SQL
- Entendiendo bases de datos y tablas
- El modelo relacional: claves primarias y foráneas
- La base de datos del curso: TiendaVerde
Módulo 2: Consultas básicas de SQL
- Instrucción SELECT
- Alias, expresiones y columnas calculadas
- Filtrando datos con WHERE
- DISTINCT y eliminación de duplicados
- Ordenando datos con ORDER BY
- Limitando resultados con LIMIT
Módulo 3: Trabajando con múltiples tablas
- Operaciones JOIN
- INNER JOIN
- LEFT JOIN
- RIGHT JOIN
- FULL OUTER JOIN
- SELF JOIN y CROSS JOIN
- Uniones de conjuntos: UNION, INTERSECT y EXCEPT
Módulo 4: Filtrado avanzado de datos
- Usando LIKE para coincidencia de patrones
- Operadores IN y BETWEEN
- Valores NULL y IS NULL
- Funciones de agregación: COUNT, SUM, AVG, MIN y MAX
- Agregando datos con GROUP BY
- Cláusula HAVING
Módulo 5: Manipulación de datos
- Creando tablas y restricciones con CREATE TABLE
- Instrucción INSERT
- Instrucción UPDATE
- Instrucción DELETE
- Instrucción UPSERT (MERGE)
- Modificando el esquema: ALTER TABLE y migraciones seguras
Módulo 6: Funciones avanzadas de SQL
- Funciones de cadena
- Funciones numéricas
- Funciones de fecha y hora
- Conversión de tipos y manejo de NULL: CAST y COALESCE
- Expresiones condicionales
Módulo 7: Subconsultas y consultas anidadas
- Introducción a subconsultas
- Subconsultas correlacionadas
- EXISTS y NOT EXISTS
- Usando subconsultas en cláusulas SELECT, FROM y WHERE
- Subconsultas o JOIN: cuál elegir
Módulo 8: Índices y optimización de rendimiento
- Entendiendo los índices
- Creación y gestión de índices
- Tipos de índice y cuándo no indexar
- Técnicas de optimización de consultas
- Análisis del rendimiento de consultas
Módulo 9: Transacciones y concurrencia
- Introducción a las transacciones
- Propiedades ACID
- Instrucciones de control de transacciones
- Niveles de aislamiento y anomalías de concurrencia
- Manejo de concurrencia: bloqueos e interbloqueos
Módulo 10: Temas avanzados
- Vistas
- Expresiones de tabla comunes (CTE)
- Funciones de ventana
- Procedimientos almacenados
- Triggers
- JSON y datos semiestructurados
Módulo 11: SQL en la práctica
- Casos de uso en el mundo real
- Mejores prácticas
- Seguridad: inyección SQL, permisos y roles
- SQL para análisis de datos
- SQL en desarrollo web
