Todo lo esencial de SQL en una sola hoja.
Consultas, comandos y operaciones clave explicadas de forma clara, ordenada y con ejemplos prácticos.
SELECT- Joins:
INNER|LEFT|RIGHT|FULL OUTER|CROSS|SELF|NATURAL - Operadores de conjunto:
UNION/UNION ALL|INTERSECT|EXCEPT/MINUS - Subconsultas avanzadas:
ANY/ALL|WITH
Los comandos DDL (Data Definition Language) permiten definir, modificar y eliminar estructuras de bases de datos como esquemas, tablas y vistas.
CREATE SCHEMA nombre_esquema;
-- o (MySQL):
CREATE DATABASE nombre_base_datos;[!NOTE] >
SCHEMA≠DATABASEen algunos motores (como MySQL/PostgreSQL). En PostgreSQL, el esquema es un contenedor lógico para objetos de base de datos como tablas, vistas, secuencias, etc. En MySQL, el esquema es equivalente a una base de datos.
CREATE TABLE tabla (
col1 datatype,
col2 datatype,
col3 datatype,
col4 datatype,
);También se puede hacer:
CREATE TABLE IF NOT EXISTS tabla ( ... );CREATE TABLE IF NO EXISTS books (
id SERIAL PRIMARY KEY,
title VARCHAR(100) NOT NULL,
author VARCHAR(100) NOT NULL
);CREATE TABLE nombre_esquema.tabla (
col1 datatype,
col2 datatype
);CREATE VIEW nombre_vista AS
SELECT columna1, columna2 FROM tabla;CREATE VIEW vista_ventas AS
SELECT fecha, SUM(total) AS total_diario
FROM ventas
GROUP BY fecha;DROP TABLE IF EXISTS tabla;
DROP VIEW IF EXISTS nombre_vista;
DROP SCHEMA IF EXISTS nombre_esquema CASCADE;
DROP DATABASE IF EXISTS nombre_base_datos;ALTER TABLE tabla ADD nueva_columna tipo;ALTER TABLE tabla RENAME COLUMN antigua_columna TO nueva_columna;-- En MySQL
ALTER TABLE tabla MODIFY columna tipo;
-- En PostgreSQL
ALTER TABLE tabla ALTER COLUMN columna TYPE nuevo_tipo;ALTER TABLE tabla DROP COLUMN columna;Borra todas las filas de una tabla existente.
TRUNCATE TABLE tabla;
TRUNCATE TABLE tabla RESTART IDENTITY; -- PostgreSQL: reinicia IDs autoDQL (Data Query Language) se utiliza para consultar datos de una base de datos. La palabra clave principal es SELECT, acompañada de múltiples cláusulas opcionales que permiten filtrar, agrupar, ordenar y combinar resultados.
SELECT * FROM tabla;
SELECT col1, col2 FROM tabla;Seleccionar / Usar una vista (view):
SELECT * FROM vista_ventas WHERE fecha = '2024-01-01';Especificar el número de registros a devolver desde la parte superior de la tabla.
-- SQL Server
SELECT TOP 10 * FROM tabla;
SELECT TOP number columnas FROM tabla WHERE condicion;
SELECT TOP percent columnas FROM tabla WHERE condicion;
-- PostgreSQL / MySQL / SQLite
SELECT * FROM tabla LIMIT 10;
SELECT * FROM tabla LIMIT 10 OFFSET 5;Note
No todos los sistemas de bases de datos soportan SELECT TOP.
El equivalente en MySQL es la cláusulaLIMIT.
Un alias es el nombre temporal que toma una tabla o columna
SELECT columna AS alias FROM tabla;
SELECT columna FROM tabla AS alias;SELECT col1 AS alias1, col2 AS alias2;
SELECT col1 AS alias1, col2 AS alias2 FROM tabla AS alias3;
SELECT t.col1, t.col2 FROM tabla AS t;SELECT * FROM tabla WHERE columna = valor;
SELECT col1, col2 FROM tabla WHERE condicion;
SELECT * FROM tabla WHERE NOT condicion;
SELECT * FROM tabla WHERE EXISTS (SELECT 1 FROM otra_tabla WHERE condicion);SELECT * FROM tabla WHERE condicion1 AND condicion2;
SELECT * FROM tabla WHERE condicion1 AND condicion2 AND ...;
SELECT * FROM tabla WHERE condicion1 OR condicion2;
SELECT * FROM tabla WHERE condicion1 OR condicion2 OR ...;
SELECT * FROM tabla WHERE condicion1 AND (condicion2 OR condicion3);SELECT * FROM tabla WHERE col1 = 'A' AND col2 > 10;
SELECT * FROM tabla WHERE col1 = 'B' OR col2 < 5;
SELECT * FROM tabla WHERE col1 = 'X' AND (col2 = 'Y' OR col3 = 'Z');SELECT * FROM tabla WHERE columna IS NULL;
SELECT * FROM tabla WHERE columna IS NOT NULL;SELECT col1, col2 FROM tabla WHERE columna BETWEEN value1 AND value2;
SELECT * FROM tabla WHERE columna BETWEEN 10 AND 20;
SELECT * FROM ventas WHERE fecha BETWEEN '2024-01-01' AND '2024-12-31';SELECT * FROM tabla WHERE columna LIKE 'a%'; -- empieza por 'a'
SELECT * FROM tabla WHERE columna LIKE '%a'; -- termina por 'a'
SELECT * FROM tabla WHERE columna LIKE '%texto%'; -- contiene 'texto'
SELECT * FROM tabla WHERE columna LIKE '_r%'; -- segundo carácter es 'r'
SELECT * FROM tabla WHERE columna LIKE 'a%b'; -- empieza por 'a' y termina por 'b'
SELECT * FROM tabla WHERE columna LIKE 'a%b%c'; -- empieza por 'a', termina por 'c' y tiene 'b' en cualquier posición%(signo porcentaje) - carácter comodín que representa cero, uno o varios caracteres.\_(underscore) - carácter comodín que representa un único carácter.
Esencialmente, el operador IN es una abreviatura de las condiciones OR múltiples.
SELECT columnas FROM tabla WHERE columna IN (value1, value2, …);
SELECT * FROM tabla WHERE columna IN ('A', 'B', 'C');
SELECT columnas FROM tabla WHERE columna IN (SELECT columna FROM otra_tabla);SELECT * FROM tabla
WHERE EXISTS (
SELECT 1
FROM otra_tabla
WHERE condicion
);SELECT name
FROM countries
WHERE EXISTS (
SELECT *
FROM cities
WHERE country_id = countries.id
)SELECT * FROM tabla ORDER BY column;
SELECT * FROM tabla ORDER BY column DESC;
SELECT * FROM tabla ORDER BY col1 ASC, col2 DESC;SELECT DISTINCT col1, col2 FROM tabla;SELECT columna, COUNT(*) FROM tabla GROUP BY columna;
SELECT departamento, COUNT(*) FROM empleados GROUP BY departamento;SELECT col1, COUNT(col2) FROM tabla WHERE condicion
GROUP BY col1 ORDER BY COUNT(col2) DESC;SELECT columna, COUNT(*) FROM tabla GROUP BY columna HAVING COUNT(*) > 10;
SELECT COUNT(col1), col2 FROM tabla GROUP BY col2 HAVING COUNT(col1) > 5;
SELECT departamento, COUNT(*) FROM empleados GROUP BY departamento HAVING COUNT(*) > 10;SELECT COUNT(*) FROM tabla;
SELECT COUNT(DISTINCT columna) FROM tabla;
SELECT SUM(total) FROM ventas;
SELECT AVG(salario) FROM empleados;
SELECT MIN(precio), MAX(precio) FROM productos;A continuación un set de tablas de ejemplo y cómo quedan los resultados tras cada tipo de JOIN.
empleados
| id | nombre | dep_id | supervisor_id |
|---|---|---|---|
| 1 | Juan | 1 | NULL |
| 2 | María | 2 | 1 |
| 3 | Pedro | 3 | 1 |
| 4 | Ana | 2 | 2 |
departamentos
| id | departamento |
|---|---|
| 1 | Marketing |
| 2 | Ventas |
| 3 | Recursos Humanos |
| 4 | Finanzas |
SELECT columnas
FROM tabla1
INNER JOIN tabla2
ON tabla1.columna = tabla2.columna;
SELECT tabla1.columna1, tabla2.columna2, tabla3.columna3
FROM ( ( tabla1
INNER JOIN tabla2
ON relacion
)
INNER JOIN tabla3
ON relacion
);SELECT e.nombre, d.departamento
FROM empleados e
INNER JOIN departamentos d
ON e.dep_id = d.id;Resultado:
| nombre | departamento |
|---|---|
| Juan | Marketing |
| María | Ventas |
| Pedro | Recursos Humanos |
| Ana | Ventas |
SELECT e.nombre, d.departamento
FROM empleados e
LEFT JOIN departamentos d
ON e.dep_id = d.id;Resultado:
| nombre | departamento |
|---|---|
| Juan | Marketing |
| María | Ventas |
| Pedro | Recursos Humanos |
| Ana | Ventas |
SELECT columnas
FROM tabla1
RIGHT JOIN tabla2
ON tabla1.columna = tabla2.columna;SELECT e.nombre, d.departamento
FROM empleados e
RIGHT JOIN departamentos d
ON e.dep_id = d.id;Resultado:
| nombre | departamento |
|---|---|
| Juan | Marketing |
| María | Ventas |
| Pedro | Recursos Humanos |
| Ana | Ventas |
| NULL | Finanzas |
SELECT columnas
FROM tabla1
FULL OUTER JOIN tabla2
ON tabla1.columna = tabla2.columna;SELECT e.nombre, d.departamento
FROM empleados e
FULL OUTER JOIN departamentos d
ON e.dep_id = d.id;Resultado:
| nombre | departamento |
|---|---|
| Juan | Marketing |
| María | Ventas |
| Pedro | Recursos Humanos |
| Ana | Ventas |
| NULL | Finanzas |
SELECT e.nombre, d.departamento
FROM empleados e
CROSS JOIN departamentos d;Resultado (4×4 = 16 filas): Ejemplo de las primeras 4 filas:
| nombre | departamento |
|---|---|
| Juan | Marketing |
| Juan | Ventas |
| Juan | Recursos Humanos |
| Juan | Finanzas |
SELECT e.nombre AS empleado,
s.nombre AS supervisor
FROM empleados e
JOIN empleados s
ON e.supervisor_id = s.id;Resultado:
| empleado | supervisor |
|---|---|
| María | Juan |
| Pedro | Juan |
| Ana | María |
Une automáticamente por columnas de mismo nombre (
dep\_id = id). Puede ser inseguro si hay nombres duplicados.
SELECT *
FROM empleados
NATURAL JOIN departamentos;Resultado equivalente a INNER JOIN:
| id | nombre | departamento |
|---|---|---|
| 1 | Juan | Marketing |
| 2 | María | Ventas |
| 3 | Pedro | Recursos Humanos |
| 4 | Ana | Ventas |
Combina los resultados de dos o más consultas SELECT en un solo conjunto de resultados.
- Cada sentencia
SELECTdebe tener el mismo número de columnas. - Las columnas deben tener el mismo tipo de datos.
- Las columnas en cada
SELECTdeben también estar en el mismo orden.
SELECT columnas FROM tabla1
UNION
SELECT columna FROM tabla2;El operador UNION solo selecciona valores distintos, UNION ALL permitirá duplicados
SELECT columnas FROM tabla1
UNION ALL
SELECT columnas FROM tabla3;Ejemplo: "Obtener los nombres de ciclistas y nadadores españoles".
SELECT name FROM cycling WHERE country = 'ES'
UNION
SELECT name FROM swimming WHERE country = 'ES';Devuelve los registros que están presentes en ambas tablas. Suele utilizarse del mismo modo que UNION.
SELECT columnas FROM tabla1
INTERSECT
SELECT columna FROM tabla2;Ejemplo: "Obtener los nombres de ciclistas que también hacen triatlón en España".
SELECT name FROM cycling WHERE country = 'ES'
INTERSECT
SELECT name FROM triathlon WHERE country = 'ES';Utilizado para devolver todos los registros de la primera sentencia SELECT que no se encuentran en la segunda sentencia SELECT. Generalmente se utiliza de la misma manera que UNION.
SELECT columnas FROM tabla1
EXCEPT
SELECT columna FROM tabla2;Ejemplo: "Obtener los nombres de ciclistas que no hacen triatlón en España".
SELECT name FROM cycling WHERE country = 'ES'
EXCEPT
SELECT name FROM triathlon WHERE country = 'ES';ANY- Devuelve verdadero si algún valor de la subconsulta cumple la condicion.ALL- Devuelve verdadero si todos los valores de la subconsulta cumplen la condicion.
SELECT * FROM tabla WHERE columna operator ANY (SELECT * FROM tabla WHERE condicion);
SELECT * FROM tabla WHERE columna operator ALL (SELECT * FROM tabla WHERE condicion);SELECT * FROM productos
WHERE precio > ANY (
SELECT precio FROM productos WHERE categoria = 'A'
);
SELECT * FROM productos
WHERE precio > ALL (
SELECT precio FROM productos WHERE categoria = 'B'
);ANY- Busca todos los productos cuyo precio sea mayor que al menos uno de los precios de la categoría A (> mínimode los valores).ALL- Busca todos los productos cuyo precio sea mayor que todos los precios de la categoría B (> máximode los valores).
Subconsultas con alias temporales
WITH alias AS (
SELECT * FROM tabla WHERE condicion
)
SELECT * FROM alias WHERE condicion;WITH empleados_activos AS (
SELECT * FROM empleados WHERE activo = TRUE
)
SELECT * FROM empleados_activos WHERE salario > 3000;Insertar una fila en todas las columnas:
INSERT INTO tabla VALUES (value1, value2 …);
INSERT INTO empleados VALUES (2, 'Rocío', 1, NULL);Insertar múltiples filas:
INSERT INTO tabla (col1, col2) VALUES
(value1, value2),
(value3, value4),
(value5, value6);
INSERT INTO empleados (id, nombre, dep_id) VALUES
(2, 'Rocío', 1),
(3, 'Elena', 2),
(4, 'Ángel', 3);Insertar desde otra tabla:
INSERT INTO tabla (col1, col2)
SELECT col1, col2
FROM otra_tabla;
INSERT INTO empleados_ventas (id, nombre)
SELECT id, nombre
FROM empleados WHERE dep_id = 2;Actualizar columnas con condición:
UPDATE tabla
SET col1 = value1, col2 = value2
WHERE condicion;
UPDATE empleados
SET salario = salario * 1.1
WHERE dep_id = 1;-- UPDATE con JOIN (PostgreSQL)
UPDATE empleados e
SET salario = s.nuevo_salario
FROM ajustes s
WHERE e.id = s.emp_id;Eliminar filas según condición:
DELETE FROM tabla WHERE condicion;
DELETE FROM empleados WHERE id = 7;Eliminar todas las filas de una tabla (mantiene la estructura):
DELETE FROM empleados;Llamar a un procedimiento almacenado:
CALL procedimiento(param1, param2);CALL sumar_sueldos(3);Bloquear una tabla para lectura/escritura (evitar modificaciones):
LOCK TABLES tabla1 READ, tabla2 WRITE;
LOCK TABLES empleados WRITE;
UNLOCK TABLES;[!NOTE] > No disponible en BigQuery (gestión de permisos a través de consola IAM y control a nivel dataset).
-- Conceder SELECT y INSERT a un usuario
GRANT SELECT, INSERT ON empleados TO juan;
-- Conceder todos los privilegios con opción de re-grant
GRANT ALL PRIVILEGES ON base_datos.* TO 'app_user'@'%'
WITH GRANT OPTION;[!NOTE] > No disponible en BigQuery (gestión de permisos a través de consola IAM y control a nivel dataset).
-- Revocar permisos
REVOKE INSERT ON empleados FROM juan;[!NOTE] > No disponible en BigQuery (gestión de permisos a través de consola IAM y control a nivel dataset).
TCL (Transaction Control Language) gestiona el control de las transacciones, asegurando la integridad de los datos. Incluye comandos para confirmar, deshacer y establecer puntos intermedios.
-- SQL Server / Oracle
BEGIN TRANSACTION;
-- MySQL / PostgreSQL (implícito tras cualquier DML)
START TRANSACTION;COMMIT;Guarda permanentemente todas las operaciones realizadas desde el inicio de la transacción.
ROLLBACK;Cancela toda la transacción, dejando la base de datos en el estado previo.
SAVEPOINT nombre_punto;ROLLBACK TO SAVEPOINT - Deshacer hasta un punto
SAVEPOINT nombre_punto;
-- .. operaciones intermedias ...
ROLLBACK TO SAVEPOINT nombre_punto;Permite deshacer hasta un punto específico sin abordar toda la transacción.
RELEASE SAVEPOINT - Eliminar un punto intermedio
SAVEPOINT nombre_punto;
-- .. operaciones intermedias ...
ROLLBACK TO SAVEPOINT nombre_punto;
RELEASE SAVEPOINT nombre_punto;-- Definir nivel de aislamiento (PostgreSQL, MySQL 8+)
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- Modo de solo lectura
SET TRANSACTION READ ONLY;Controla concurrencia y visibilidad de datos entre transacciones.


