Consultas avanzadas · subconsultas

LATERAL en SQL y APPLY en SQL Server

Haz que una subconsulta de FROM dependa de la fila que tiene a su izquierda: una forma directa de pedir, por ejemplo, el último pedido de cada cliente.

Lectura: 7–9 minResultado comprobadoPráctica con pistas
Contenido de esta guía

Qué problema resuelve LATERAL

Una subconsulta normal dentro de FROM se comporta como una tabla derivada independiente. LATERAL cambia esa relación: permite que la subconsulta use columnas de elementos anteriores del mismo FROM.

La idea mental es sencilla: toma una fila de la izquierda y ejecuta la subconsulta usando sus valores. Después combina el resultado con esa fila. Es especialmente útil cuando necesitas obtener una o varias filas relacionadas por cada elemento exterior, como el pedido más reciente de cada cliente o los dos productos más vendidos de cada categoría.

Sintaxis básica

PostgreSQL / MySQL 8.4
SELECT ...
FROM tabla_exterior AS t
LEFT JOIN LATERAL (
  SELECT ...
  FROM tabla_relacionada AS r
  WHERE r.clave = t.clave
  ORDER BY ...
  LIMIT 1
) AS x ON TRUE;

La referencia a t.clave dentro de la subconsulta es lo importante: la tabla derivada depende de la fila exterior. Con LEFT JOIN LATERAL, una fila exterior puede conservarse aunque la subconsulta no encuentre coincidencias.

Ejemplo: último pedido de cada cliente

Queremos una fila por cliente con su pedido más reciente. Además, queremos conservar a los clientes que todavía no tienen pedidos.

PostgreSQL / MySQL 8.4
SELECT c.id,
       c.nombre,
       ultimo.id AS pedido_id,
       ultimo.fecha,
       ultimo.total
FROM clientes AS c
LEFT JOIN LATERAL (
  SELECT p.id, p.fecha, p.total
  FROM pedidos AS p
  WHERE p.cliente_id = c.id
  ORDER BY p.fecha DESC, p.id DESC
  LIMIT 1
) AS ultimo ON TRUE
ORDER BY c.id;
Resultado con los datos educativos
idnombrepedido_idfechatotal
1Ana Torres1112025-06-01249.0
2Luis Martín1142025-06-08203.9
3Marta Ruiz1162025-06-12999.0
4Diego López1052025-05-1569.9
5Sara Gómez1152025-06-1024.0
6Pablo SanzNULLNULLNULL

La subconsulta ordena solo los pedidos del cliente que se está procesando y conserva el primero. El desempate por p.id DESC hace determinista la elección si dos pedidos comparten fecha. Pablo aparece con valores NULL porque LEFT JOIN LATERAL mantiene la fila exterior aunque no exista pedido.

El resultado se comprobó con el mismo conjunto educativo mediante una consulta equivalente con ROW_NUMBER() en el motor local.

CROSS JOIN LATERAL frente a LEFT JOIN LATERAL

  • CROSS JOIN LATERAL / JOIN LATERAL: si la subconsulta no devuelve filas, esa fila exterior desaparece del resultado.
  • LEFT JOIN LATERAL: conserva la fila exterior y rellena con NULL las columnas del resultado lateral cuando no hay coincidencia.

La elección se parece a la diferencia conceptual entre INNER JOIN y LEFT JOIN: decide si necesitas conservar filas sin relación.

SQL Server: CROSS APPLY y OUTER APPLY

SQL Server expresa este patrón con APPLY. CROSS APPLY elimina la fila izquierda cuando la parte derecha no devuelve nada; OUTER APPLY la conserva.

SQL Server
SELECT c.id,
       c.nombre,
       ultimo.id AS pedido_id,
       ultimo.fecha,
       ultimo.total
FROM clientes AS c
OUTER APPLY (
  SELECT TOP (1) p.id, p.fecha, p.total
  FROM pedidos AS p
  WHERE p.cliente_id = c.id
  ORDER BY p.fecha DESC, p.id DESC
) AS ultimo
ORDER BY c.id;

No copies una sintaxis de un motor a otro de forma mecánica: la intención es equivalente, pero palabras clave y formas de limitar filas cambian.

Cuándo usar una alternativa

LATERAL no es la única manera de resolver «una fila relacionada por cada grupo». Una función de ventana con ROW_NUMBER() suele ser más portable y puede resultar más clara cuando quieres clasificar todo el conjunto antes de filtrar. Una subconsulta correlacionada escalar también puede servir si solo necesitas devolver un único valor.

No asumas que LATERAL es más rápido por definición. Los optimizadores pueden reescribir consultas y elegir planes distintos según índices, cardinalidades y distribución de datos. Para rendimiento, compara planes con EXPLAIN o la herramienta equivalente del motor real.

Olvidar que la subconsulta depende de cada fila exterior

Si la parte lateral devuelve muchas filas por cada cliente, el resultado puede crecer rápidamente. Antes de añadir LIMIT, filtros u ordenación, define cuántas filas necesitas realmente por elemento exterior.

Comprueba lo aprendido

Intermedia · JOIN y subconsultas

Conserva clientes aunque no tengan pedidos

Escribe la consulta de PostgreSQL/MySQL que devuelva nombre, pedido_id y fecha del pedido más reciente de cada cliente. Los clientes sin pedidos también deben aparecer.

Criterio de éxito: usas una subconsulta lateral correlacionada con c.id, ordenas por fecha e id descendentes y eliges una sola fila.

Qué debes recordar

  • LATERAL permite que una subconsulta de FROM use columnas de elementos anteriores.
  • LEFT JOIN LATERAL conserva filas exteriores sin coincidencia.
  • SQL Server resuelve el mismo tipo de dependencia con CROSS APPLY y OUTER APPLY.
  • ROW_NUMBER() y subconsultas correlacionadas pueden ser alternativas más adecuadas según la intención.
  • El rendimiento depende del plan y de los datos; mídelo en el motor real.

Conceptos relacionados

Fuentes técnicas consultadas