English

Manual de campo · trampas de SQL

¿Por qué un self-join siempre trae una fila de más?

Unir una tabla contra sí misma sin excluir la fila consigo misma hace que cada registro se empareje con su propia copia: una fila que no dice nada, pero que sí cuenta.

Cuándo aparece

Comparar filas de la misma tabla entre sí: quién coincidió con quién, duplicados, pares, solapes. Cualquier self-join sin una condición que descarte la pareja trivial.

Ejemplo

Mal: sin excluir la pareja trivial

SELECT o.socio, o.desde, v.socio AS con_quien
FROM estancias o
JOIN estancias v
  ON o.sala = v.sala
 AND o.desde < v.hasta
 AND v.desde < o.hasta;
-- cada estancia solapa consigo misma (o.socio = v.socio en dos filas):
-- esas filas no aportan nada y encima inflan cualquier conteo posterior

Bien: excluir la pareja consigo mismo

SELECT o.socio, o.desde, v.socio AS con_quien
FROM estancias o
JOIN estancias v
  ON o.sala = v.sala
 AND o.id <> v.id
 AND o.desde < v.hasta
 AND v.desde < o.hasta;

Sin una condición que compare la clave de una copia contra la otra, cada fila de la tabla siempre encuentra pareja consigo misma: mismo salón, mismo horario, solapa perfectamente porque es la misma estancia. o.id <> v.id (o el equivalente con la clave primaria) elimina exactamente esas filas y sólo esas. El error es fácil de no ver porque la fila trivial suele parecer razonable a simple vista, alguien 'coincidió consigo mismo', y sólo se nota cuando el resultado trae más filas de las esperadas, o cuando un count(*) posterior sale inflado en exactamente una unidad por cada fila original.

Esta trampa está escondida en un caso de verdad, con datos de verdad.

Jugar el caso 1 gratis →

Trampas relacionadas