Te habrá pasado más de una vez: necesitas sacar todos los valores de la Tabla1 que no aparezcan en la Tabla2. Es decir, la operación opuesta a un INNER JOIN. En muchos casos vemos que hay quien usa un NOT IN() como solución:
Nota: Asumimos que las tablas están bien formadas y que la Tabla1 se relaciona con la Tabla2 por medio de una clave externa (en el ejemplo será el campo IdClaveExterna en Tabla2 que está relacionado con el campo id de Tabla1)
SELECT * FROM Tabla1 WHERE Tabla1.id NOT IN (SELECT IdClaveExterna FROM Tabla2)
Y esto está mal. Muy mal. Porque el IN() tiene un rendimiento muy bajo, como hemos visto en el pasado, y su negación pues todavía ofrece uno peor. Entonces ¿cómo lo hacemos? No tenemos una unión que sea ANTI JOIN, pero lo podemos resolver de la siguiente forma ya que tenemos un campo Id en cada tabla para cada fila sirviendo como clave primaria:
SELECT * FROM Tabla1 LEFT JOIN Tabla2 ON Tabla1.id = Tabla2.idClaveExterna WHERE Tabla2.id IS NULL
De esta forma cogemos todos los valores de la Tabla1 unidos a la Tabla2 por la clave externa, pero descartando de la consulta aquellos valores que nos devuelvan nulo el valor de la clave primaria de la Tabla2.
Pingback: SQL-Server: Hacer un anti-join con EXCEPT – DonnierocK