Bases de datos y SQL
Una base de datos relacional guarda la información en tablas: cada tabla tiene filas (registros) y columnas (campos), igual que una hoja de cálculo, pero con reglas estrictas que garantizan que los datos sean consistentes. SQL (Structured Query Language) es el idioma universal para hablar con esas bases de datos.
empleados es una ficha
por fila, y cada columna es un dato bien definido (nombre, salario, fecha de contrato…). SQL te permite
hacer preguntas: «dame todos los empleados de Desarrollo con salario mayor de 30.000».1.1 · Conceptos fundamentales
empleados)id)1.2 · Motor recomendado: MySQL
Instala MySQL Server desde mysql.com (o el paquete mysql-server
de tu Linux). También vale MariaDB: es 100 % compatible para este curso.
Instala una herramienta gráfica: MySQL Workbench (recomendada) para escribir y ejecutar
consultas cómodamente, o usa la terminal: mysql -u root -p.
Carga el dataset del bloque: descarga sql/sql-bloque1_empleados.sql y
ejecútalo con mysql -u root -p < sql-bloque1_empleados.sql o pegándolo en Workbench.
1.3 · Tu base de datos lista
Al ejecutar el fichero se crea la base tw_empleados con una tabla empleados y 40
filas. Compruébalo:
SHOW DATABASES;
USE tw_empleados;
SHOW TABLES;
DESCRIBE empleados;
DESCRIBE (o DESC) te muestra las columnas de una tabla, su tipo
y si aceptan NULL. Es tu mejor amigo cuando empiezas con una base de datos nueva.Primer SELECT
La instrucción SELECT lee datos. Su estructura más básica es
SELECT columnas FROM tabla;. Se lee así: «selecciona estas columnas desde esta tabla».
2.1 · Seleccionar todo: el asterisco
SELECT *
FROM empleados;
* significa «todas las columnas». Es cómodo para explorar, pero en producción conviene pedir
solo lo que necesitas: menos tráfico y más claro el resultado.
2.2 · Elegir columnas
SELECT nombre, salario
FROM empleados;
2.3 · Alias con AS
Con AS pones un nombre más legible a una columna o a una expresión calculada:
SELECT nombre AS empleado, salario AS sueldo_mensual
FROM empleados;
SELECT nombre,
salario * 1.10 AS salario_anual_zona,
apellido
FROM empleados;
AS es opcional (SELECT salario sueldo FROM… funciona),
úsalo siempre: hace las consultas mucho más legibles y evita ambigüedades en bloques avanzados.2.4 · Comentarios en SQL
-- Comentario de una línea: todo lo que va de " -- " hasta el final
SELECT nombre, puesto -- los comentarios pueden ir al final de una sentencia
FROM empleados;
/* Comentario de bloque:
varias líneas con dash y asterisco */
WHERE y operadores
WHERE filtra filas antes de devolver el resultado. Sin él, una consulta devuelve toda la tabla; con él, solo las filas que cumplen la condición.
3.1 · Operadores de comparación
SELECT nombre, apellido, salario
FROM empleados
WHERE departamento = 'Desarrollo';
SELECT nombre, apellido, salario
FROM empleados
WHERE salario >= 30000;
| Operador | Significado | Ejemplo |
|---|---|---|
= | Igual que | puesto = 'Analista' |
<> o != | Distinto de | ciudad != 'Madrid' |
> < | Mayor / menor | salario > 30000 |
>= <= | Mayor o igual / menor o igual | salario <= 32000 |
departamento = 'Datos'. Los números van sin comillas: salario > 28000.
Mezclarlos es un error súper habitual al empezar.3.2 · Operadores lógicos: AND, OR, NOT
-- AND: deben cumplirse las dos condiciones
SELECT nombre, departamento, salario
FROM empleados
WHERE departamento = 'Desarrollo'
AND salario >= 32000;
-- OR: basta con que se cumpla una
SELECT nombre, puesto
FROM empleados
WHERE puesto = 'Soporte técnico'
OR puesto = 'Administrador Sys.';
-- NOT: niega una condición
SELECT nombre, departamento
FROM empleados
WHERE NOT departamento = 'Diseño';
3.3 · Precedencia: los paréntesis mandan
En SQL se evalúa primero NOT, luego AND y por último OR. Cuando
combinas varios, usa paréntesis para que el motor (y tú) lo entendáis igual:
SELECT nombre, departamento, salario
FROM empleados
WHERE departamento = 'Datos'
OR (departamento = 'Sistemas' AND salario >= 32000);
Ordenar y limitar
4.1 · ORDER BY
ORDER BY ordena las filas del resultado. Por defecto es ascendente; con
DESC lo hace descendente:
SELECT nombre, salario
FROM empleados
ORDER BY salario DESC;
Puedes ordenar por varias columnas. Se aplican en orden: primero el primer criterio, y para los empates, el segundo:
SELECT departamento, salario, nombre, apellido
FROM empleados
ORDER BY departamento ASC, salario DESC;
ORDER BY 2 DESC (ordenar por la segunda columna del SELECT).4.2 · LIMIT y OFFSET
LIMIT limita el número de filas devueltas. OFFSET se salta las primeras filas. Es la forma de montar paginación («página 2»):
SELECT nombre, salario
FROM empleados
ORDER BY salario DESC
LIMIT 3;
SELECT nombre, salario
FROM empleados
ORDER BY salario DESC
LIMIT 3 OFFSET 3;
4.3 · DISTINCT: valores únicos
DISTINCT elimina duplicados del resultado. Perfecto para saber «qué valores existen» en una columna:
SELECT DISTINCT departamento
FROM empleados;
LIMIT no es lo mismo que DISTINCT: LIMIT corta filas del
resultado (puede quedar duplicado), DISTINCT agrupa valores repetidos en uno solo.Texto y valores especiales
5.1 · LIKE: buscas con comodines
LIKE compara texto con dos comodines: % (cualquier secuencia) y _
(un solo carácter):
SELECT nombre, apellido, departamento
FROM empleados
WHERE apellido LIKE 'G%';
'G%' — apellidos que empiezan por G'%ez' — apellidos que terminan en "ez"'%ca%' — apellidos que contienen "ca"'a_na' — exactamente 4 letras, la 2ª cualquier y la 3ª "n"LIKE no distingue mayúsculas ni tildes. También tienes
NOT LIKE para buscar lo que NO cumple el patrón.5.2 · IN y BETWEEN
SELECT nombre, departamento
FROM empleados
WHERE departamento IN ('Datos', 'Marketing', 'Producto');
SELECT nombre, salario, contratado
FROM empleados
WHERE salario BETWEEN 30000 AND 36000
AND contratado BETWEEN '2020-01-01' AND '2022-12-31';
BETWEEN es inclusivo: incluye los extremos. Y las fechas
van entre comillas en formato 'AAAA-MM-DD'.5.3 · Valor NULL: "sin dato"
NULL NO es cero ni texto vacío: significa sin valor. No se compara con =,
se detecta con IS NULL o IS NOT NULL:
SELECT nombre, apellido, email
FROM empleados
WHERE email IS NULL;
SELECT nombre, apellido, email
FROM empleados
WHERE email IS NOT NULL;
email = NULL siempre da falso. Si lo escribes con =, el motor no
te dará error pero tampoco resultados: usa SIEMPRE IS NULL/IS NOT NULL.5.4 · Funciones básicas de texto
SELECT UPPER(nombre) AS mayuscula,
LOWER(apellido) AS minuscula,
LENGTH(nombre) AS num_letras,
CONCAT(nombre, ' ', apellido) AS nombre_completo
FROM empleados
LIMIT 5;
✍️ Los 15 ejercicios del bloque
Abre MySQL Workbench, conecta con tu servidor y ejecuta las consultas sobre la base
tw_empleados. Escribe siempre las palabras clave en mayúsculas y añade un comentario
-- con el número del ejercicio.
mysql -u root -p < sql/sql-bloque1_empleados.sql.Sección A · Primeras consultas
1 La tabla al completo
Escribe una consulta que devuelva todas las columnas de empleados. Añade
al inicio un comentario -- con el ejercicio.
Ver solución
-- Ejercicio 1: ver toda la tabla
SELECT *
FROM empleados;
2 Columnas con alias
Devuelve nombre, apellido y puesto, renombrando cada columna con
un alias en español: nombre → empleado, apellido → apellidos y
puesto → cargo.
Ver solución
-- Ejercicio 2: alias en columnas
SELECT nombre AS empleado,
apellido AS apellidos,
puesto AS cargo
FROM empleados;
3 Puestos sin repetir
Muestra la lista de puestos distintos que existen en la empresa usando
DISTINCT.
Ver solución
-- Ejercicio 3: puestos únicos
SELECT DISTINCT puesto
FROM empleados;
4 Columna calculada
Devuelve nombre, apellido y el salario multiplicado por 1.06 (una
subida ficticia del 6 %), con el alias salario_con_subida.
Ver solución
-- Ejercicio 4: subida simulada del 6%
SELECT nombre,
apellido,
salario * 1.06 AS salario_con_subida
FROM empleados;
5 Nombre completo
Combina nombre y apellido en una sola columna con CONCAT y espacio
entre medias. El alias debe ser nombre_completo. Muestra también departamento.
Ver solución
-- Ejercicio 5: construir el nombre completo
SELECT CONCAT(nombre, ' ', apellido) AS nombre_completo,
departamento
FROM empleados;
Sección B · Filtrar con WHERE
6 Un departamento concreto
Devuelve a todos los empleados de Desarrollo (nombre, apellido y puesto).
Ver solución
-- Ejercicio 6: equipo de Desarrollo
SELECT nombre, apellido, puesto
FROM empleados
WHERE departamento = 'Desarrollo';
7 Salario mínimo exigido
Devuelve nombre, apellido y salario de quien gane 30.000 € o más, ordenado de mayor a menor salario.
Ver solución
-- Ejercicio 7: salarios altos
SELECT nombre, apellido, salario
FROM empleados
WHERE salario >= 30000
ORDER BY salario DESC;
8 Dos condiciones a la vez
Con AND: empleados del departamento Datos contratados a partir del
'2021-01-01'. Muestra nombre, apellido y fecha de contrato.
Ver solución
-- Ejercicio 8: datos y contratados recientes
SELECT nombre, apellido, contratado
FROM empleados
WHERE departamento = 'Datos'
AND contratado >= '2021-01-01';
9 Cualquiera de dos puestos
Con OR: empleados que sean Analista de datos o Diseñadora/Or UX.
Fíjate en que en el dataset conviven formas femeninas y masculinas del puesto.
Ver solución
-- Ejercicio 9: dos puestos diferentes
SELECT nombre, apellido, puesto
FROM empleados
WHERE puesto LIKE 'Analista de datos'
OR puesto LIKE '%UX%';
10 Con NOT
Empleados que no sean del departamento Diseño. Muestra nombre y departamento, ordena por departamento.
Ver solución
-- Ejercicio 10: todo menos Diseño
SELECT nombre, departamento
FROM empleados
WHERE NOT departamento = 'Diseño'
ORDER BY departamento;
Sección C · Texto, rangos y NULL
11 Buscar por patrón
Empleados cuyo apellido termine en "es", ordenados alfabéticamente por apellido.
Ver solución
-- Ejercicio 11: apellidos acabados en "es"
SELECT nombre, apellido
FROM empleados
WHERE apellido LIKE '%es'
ORDER BY apellido;
12 Con IN
Con IN: empleados de los departamentos Datos, Sistemas o
Marketing. Muestra nombre, apellido y departamento.
Ver solución
-- Ejercicio 12: varios departamentos con IN
SELECT nombre, apellido, departamento
FROM empleados
WHERE departamento IN ('Datos', 'Sistemas', 'Marketing');
13 Rango con BETWEEN
Empleados con salario entre 24.000 y 30.000 € (inclusive). Muestra nombre, apellido y salario ordenados por salario ascendente.
Ver solución
-- Ejercicio 13: salarios entre 24000 y 30000
SELECT nombre, apellido, salario
FROM empleados
WHERE salario BETWEEN 24000 AND 30000
ORDER BY salario;
14 Sin email registrado
Empleados cuyo email sea NULL. Muestra nombre, apellido y departamento.
Ver solución
-- Ejercicio 14: sin email
SELECT nombre, apellido, departamento
FROM empleados
WHERE email IS NULL;
Sección D · Ordenar y limitar
15 Top 5 por salario
Los 5 empleados mejor pagados de la empresa usando ORDER BY y
LIMIT.
Ver solución
-- Ejercicio 15: top 5 por salario
SELECT nombre, apellido, salario
FROM empleados
ORDER BY salario DESC
LIMIT 5;
16 🏆 Proyecto integrador: informe de salarios altos
Crea el fichero informe_salarios.sql en el que, sobre tw_empleados, construyas
una sola consulta que devuelva los empleados de Desarrollo o Datos con un
salario mayor o igual a 30.000, ordenados por salario descendente, mostrando el
nombre, apellido, departamento y salario (con alias
completo), y limitando el resultado a 10 filas. Requisitos:
- Comentario
--al inicio explicando qué hace el informe. - Palabras clave en mayúsculas.
- Filtro con
WHEREcombinandoINyBETWEEN(o>=). - Ordenación con
ORDER BY … DESC. - Límite con
LIMIT.
Ver una solución posible
-- Informe: empleados técnicos bien pagados (Desarrollo y Datos, ≥ 30000)
SELECT nombre AS empleado,
apellido AS apellidos,
departamento AS equipo,
salario AS sueldo
FROM empleados
WHERE departamento IN ('Desarrollo', 'Datos')
AND salario >= 30000
ORDER BY salario DESC
LIMIT 10;
📝 Examen del Bloque 1
Dos partes: un test teórico autoevaluable (mínimo 70 %) y un reto práctico de autocorrección con laboratorio.
Parte B · Reto «informe de empleados»
Crea informe_empleados.sql: una consulta que devuelva los 10 empleados de la empresa
contratados desde 2020, con su nombre completo (CONCAT), departamento y salario con aliases, ordenados por
salario descendente. Tu SQL no se ejecuta en el laboratorio: se valida con reglas automáticas. Mínimo para
aprobar: 6 de 8 casillas.
Cumplidos: 0 / 8