Chuleta de SQL (PostgreSQL)

Las sentencias que más necesitas, con un ejemplo de cada una. Los ejemplos se ejecutan sobre la base de datos de práctica de la panadería y usan la sintaxis de PostgreSQL. Otras bases de datos difieren en pequeños detalles, que se indican donde importan.

Leer y filtrar

SELECT elige las columnas, FROM indica la tabla, WHERE conserva las filas que coinciden, ORDER BY ordena y LIMIT recorta el resultado. El texto va entre comillas simples.

SELECT name, unit_price
FROM products
WHERE category = 'pastry' AND unit_price < 3
ORDER BY unit_price DESC
LIMIT 5;

Resultado: Los productos de bollería por debajo de 3.00, del más caro al más barato.

Patrones, listas, rangos y NULL

LIKE busca patrones (% es cualquier texto, _ es un carácter; ILIKE ignora las mayúsculas). IN comprueba una lista, BETWEEN comprueba un rango con los extremos incluidos e IS NULL encuentra valores que faltan.

SELECT first_name, loyalty_tier
FROM customers
WHERE first_name LIKE 'A%' OR loyalty_tier IS NULL
ORDER BY first_name;

Resultado: Los clientes cuyo nombre empieza por A, o que no tienen nivel de fidelidad.

Resumir con GROUP BY

COUNT, SUM, AVG, MIN y MAX convierten las filas en un valor por grupo. WHERE filtra las filas antes de agrupar y HAVING filtra los grupos.

SELECT channel, COUNT(*) AS orders
FROM orders
GROUP BY channel
HAVING COUNT(*) > 5
ORDER BY channel;

Resultado: Solo el canal online, con 7 pedidos.

Unir tablas

INNER JOIN conserva las coincidencias y LEFT JOIN conserva cada fila de la tabla izquierda. Da a las tablas alias cortos y une siempre por la clave.

SELECT p.name, SUM(oi.quantity) AS units
FROM products AS p
JOIN order_items AS oi ON oi.product_id = p.product_id
GROUP BY p.name
ORDER BY units DESC, p.name
LIMIT 3;

Resultado: Los tres productos más vendidos.

CASE: un if/else en SQL

CASE devuelve el valor de la primera condición que se cumple, como SI.CONJUNTO en Excel. Sin ELSE devuelve NULL.

SELECT name,
       CASE WHEN unit_price < 3 THEN 'budget' WHEN unit_price <= 4 THEN 'standard' ELSE 'premium' END AS band
FROM products
ORDER BY product_id;

Resultado: Cada producto etiquetado como budget, standard o premium.

Subconsultas y WITH

Una subconsulta es una consulta dentro de otra. WITH le da nombre a una, para que la consulta principal se lea como una historia.

WITH spend AS (
  SELECT o.customer_id, SUM(oi.quantity * p.unit_price) AS total
  FROM orders AS o
  JOIN order_items AS oi ON oi.order_id = o.order_id
  JOIN products AS p ON p.product_id = oi.product_id
  GROUP BY o.customer_id
)
SELECT customer_id, total FROM spend WHERE total > 30 ORDER BY total DESC;

Resultado: El cliente 1 (Lopez) con 37.10 y el cliente 3 (Dubois) con 36.00.

Funciones de ventana

OVER añade un cálculo entre filas sin contraerlas: rankings, totales acumulados y LAG/LEAD para la fila anterior y la siguiente.

SELECT order_id, order_date,
       RANK() OVER (ORDER BY order_date) AS day_rank,
       LAG(order_date) OVER (ORDER BY order_id) AS prev_date
FROM orders
ORDER BY order_id;

Resultado: Cada pedido con su posición en el ranking por fecha y la fecha del pedido anterior.

Cambiar datos

INSERT añade filas, UPDATE las modifica y DELETE las elimina. Incluye siempre WHERE en UPDATE y DELETE, y ejecuta primero la consulta como SELECT para ver qué afectaría. Envuelve los cambios delicados entre BEGIN y ROLLBACK.

UPDATE products
SET unit_price = unit_price + 0.10
WHERE category = 'drinks'
RETURNING name, unit_price;

Resultado: Las dos bebidas con sus nuevos precios.

Preguntas frecuentes

¿En qué orden ejecuta SQL una consulta?
Primero FROM y JOIN, luego WHERE, GROUP BY, HAVING, SELECT, ORDER BY y, por último, LIMIT. Por eso un WHERE no puede usar un alias de columna definido en SELECT, pero ORDER BY sí puede.
¿SQL distingue entre mayúsculas y minúsculas?
Las palabras clave y los nombres de tablas y columnas, no (PostgreSQL convierte a minúsculas los nombres sin comillas). Los valores de texto sí: 'Paris' y 'paris' son distintos, salvo que uses ILIKE o LOWER().
¿Funciona esto en MySQL, SQL Server o SQLite?
El núcleo (SELECT, WHERE, GROUP BY, JOIN, CASE) sí. Las diferencias están en LIMIT (TOP en SQL Server), la concatenación de cadenas, las funciones de fecha y RETURNING. Consulta la documentación de tu base de datos para esos casos.

Practícalo