0Pricing
Coding Interview Prep · Lección

Expansión de joins y multiplicación de filas

Descubra por qué un join puede devolver más filas que cualquiera de las tablas y cómo lo evalúan los entrevistadores

Expansión de joins y multiplicación de filas es una lección gratuita de Coding Interview Prep en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Coding Interview Prep, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Coding Interview Prep incluye 4 lecciones en total.

Cuando una unión devuelve demasiadas filas

Una de las preguntas de entrevista más reveladoras parece inocente: «¿puede una unión devolver más filas que la tabla más grande?» La respuesta es sí, y el fenómeno se denomina fan-out o multiplicación de filas.

Los candidatos que dicen «una unión simplemente combina tablas» no detectan el problema. Quienes pueden predecir el número exacto de filas consiguen el puesto. Esta lección desarrolla esa capacidad de predicción.

La causa: coincidencias de uno a muchos

El fan-out ocurre cuando una fila de la izquierda coincide con muchas filas de la derecha. Cada coincidencia produce una fila de salida independiente.

Con clientes y pedidos, Ada (una cliente) tiene dos pedidos. La unión emite una fila por pedido, por lo que Ada aparece duplicada. Los campos del cliente se repiten; solo cambian los campos del pedido.

SELECT c.name, o.amount
FROM customers c
JOIN orders o ON o.customer_id = c.id;
-- Ada appears twice (she has 2 orders)
-- name | amount
-- Ada  | 50
-- Ada  | 20
-- Bob  | 99

Contar las filas de salida

El número de filas de salida equivale a la suma de coincidencias por cada fila izquierda, no al número de clientes.

  • Ada -> 2 pedidos -> 2 filas
  • Bob -> 1 pedido -> 1 fila
  • Cleo -> 0 pedidos -> 0 filas (se descarta mediante INNER JOIN)

Total = 3 filas, aunque customers también tiene 3 filas. Si Ada pasa a tener 10 pedidos, el resultado aumenta a 11 filas.

Las relaciones de muchos a muchos explotan

El fan-out se multiplica cuando ambos lados tienen varias coincidencias para la misma clave. Si la clave K aparece 3 veces a la izquierda y 4 veces a la derecha, la unión produce 3 x 4 = 12 filas para esa clave.

Así es como una unión aparentemente pequeña puede crecer hasta millones de filas. A los entrevistadores les encanta proporcionar claves duplicadas en ambos lados para comprobar si detecta la multiplicación.

-- left has 3 rows with tag 'A', right has 4 rows with tag 'A'
SELECT l.id, r.id
FROM left_t l
JOIN right_t r ON r.tag = l.tag;
-- tag 'A' alone yields 3 * 4 = 12 output rows

La trampa de la agregación

Este es el error que los entrevistadores provocan con más frecuencia. Une orders con order_items para obtener los detalles de los artículos y, después, calcula SUM del importe del pedido. Como cada pedido se multiplica en varias filas de artículos, el importe del pedido se cuenta una vez por artículo.

El SUM queda enormemente inflado. La consulta parece correcta e incluso se ejecuta, y eso es precisamente lo que la hace peligrosa.

-- BUG: order.amount duplicated across items
SELECT SUM(o.amount) AS total
FROM orders o
JOIN order_items i ON i.order_id = o.id;
-- a 3-item order counts o.amount 3 times

Cómo se produce la inflación

Suponga que un pedido tiene un importe de 100 y tres artículos. La unión produce tres filas, cada una con el importe 100. SUM(o.amount) devuelve 300, no 100.

La solución consiste en agregar con la granularidad correcta: sume los artículos o sume por separado los pedidos distintos. Nunca aplique SUM a un valor de la entidad principal a través de una unión con multiplicación de filas secundarias.

o.id | o.amount | i.id
7    | 100      | 71
7    | 100      | 72
7    | 100      | 73
-- SUM(o.amount) = 300  (WRONG, should be 100)

Solución 1: agregar primero la tabla secundaria

La solución más limpia consiste en preagregar el lado de muchos en una subconsulta o CTE para que cada entidad principal coincida exactamente con una fila resumida. Sin fan-out ni inflación.

Aquí reducimos los artículos a una fila por pedido antes de unirlos, de modo que el importe de la entidad principal nunca se duplica.

SELECT o.id, o.amount, i.item_count
FROM orders o
JOIN (
  SELECT order_id, COUNT(*) AS item_count
  FROM order_items
  GROUP BY order_id
) i ON i.order_id = o.id;

Solución 2: COUNT(DISTINCT) y sumas condicionales

Si debe agregar después de una unión con multiplicación de filas, cuente o sume con la granularidad correcta. Utilice COUNT(DISTINCT o.id) para contar pedidos en lugar de filas de artículos.

Nota: SUM(DISTINCT o.amount) NO es una solución segura, porque dos pedidos diferentes pueden tener legítimamente el mismo importe y se combinarían. La preagregación es más fiable.

SELECT COUNT(DISTINCT o.id)   AS num_orders,
       COUNT(i.id)            AS num_items
FROM orders o
JOIN order_items i ON i.order_id = o.id;

Detectar el fan-out antes de que cause problemas

Un diagnóstico rápido que suele gustar a los entrevistadores: compruebe si la clave de unión es única en el lado que espera que sea el «uno». Si el número de claves distintas es menor que el número de filas, ese lado tiene duplicados y provocará fan-out.

-- if this returns rows, order_id is NOT unique in order_items
SELECT order_id, COUNT(*) AS n
FROM order_items
GROUP BY order_id
HAVING COUNT(*) > 1;

Verificar la granularidad con un recuento

Antes de confiar en cualquier agregado sobre un resultado unido, compruebe que el número de filas sea razonable. Un truco rápido consiste en comparar el recuento de la unión con el recuento de la tabla que espera que defina la granularidad.

Si COUNT(*) sobre la unión es mayor que COUNT(*) de orders, la unión ha provocado fan-out y cualquier agregado por pedido está en riesgo. Esta comprobación de una línea ha salvado muchas respuestas en entrevistas.

-- joined rows should equal order count if no fan-out
SELECT COUNT(*) AS joined_rows
FROM orders o
JOIN order_items i ON i.order_id = o.id;

SELECT COUNT(*) AS order_rows FROM orders;
-- joined_rows > order_rows  =>  fan-out present

El fan-out no siempre es un error

A veces quiere una fila por entidad secundaria. Enumerar cada artículo con los datos de cabecera de su pedido es un fan-out correcto. La clave está en conocer la granularidad objetivo: ¿cuántas filas debe producir cada entidad?

Declare la granularidad antes de escribir la consulta. «Quiero una fila por artículo del pedido» frente a «una fila por pedido» determina si el fan-out es una característica o un error.

Comprobación rápida

Prediga el resultado de una unión de uno a muchos.

Resumen: fan-out y multiplicación de filas

Lo que debe recordar:

  • Una unión emite una fila por cada par coincidente, por lo que las coincidencias de uno a muchos duplican el lado «uno».
  • Las claves de muchos a muchos se multiplican: 3 x 4 = 12 filas para esa clave.
  • Agregar un valor de la entidad principal a través de una unión con fan-out infla las sumas y los recuentos.
  • Corríjalo preagregando la tabla secundaria o contando y sumando con la granularidad correcta, por ejemplo, mediante COUNT(DISTINCT).
  • Declare siempre primero la granularidad prevista; el fan-out solo es un error cuando la incumple.

Preguntas frecuentes

¿La lección «Expansión de joins y multiplicación de filas» es gratis?

Sí — el texto completo de «Expansión de joins y multiplicación de filas» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Coding Interview Prep, actualiza a CoddyKit PRO. El curso de Coding Interview Prep incluye 4 lecciones en total.

¿Qué aprenderé en «Expansión de joins y multiplicación de filas»?

Descubra por qué un join puede devolver más filas que cualquiera de las tablas y cómo lo evalúan los entrevistadores Practicas Coding Interview Prep con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Coding Interview Prep?

No se requiere experiencia previa. Coding Interview Prep en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Expansión de joins y multiplicación de filas»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Coding Interview Prep?

Sí. Cada lección de Coding Interview Prep incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Cómo INNER JOIN hace coincidir las filas
  2. ON frente a WHERE en los joins
  3. Expansión de joins y multiplicación de filas
  4. Unir tres o más tablas
← Volver a Coding Interview Prep