A veces podemos necesitar borrar filas de una tabla, pero las filas que queremos borrar dependen de una o más condiciones de otra tabla.

Por ejemplo, escribimos esta consulta:

SELECT
   E.EMP_NOMBRE,
   E.EMP_APELLD,
   P.PRO_IDENTI,
   P.PRO_NOMBRE
FROM
   EMPLEADOS   E
JOIN
   PROFESIONES P
   ON E.EMP_IDEPRO = P.PRO_IDENTI
WHERE
   P.PRO_NOMBRE = 'Secretaria'

Y obtenemos este resultado, que nos muestra a todas las “Secretarias” que tenemos:

BORRAR1

Captura 1. Si haces clic en la imagen la verás más grande

Fíjate que la condición para mostrar las filas (la que se encuentra en el WHERE) depende de la tabla PROFESIONES, no de la tabla EMPLEADOS. Nuestra tabla principal es EMPLEADOS, pero la condición se encuentra en otra tabla, en la tabla de PROFESIONES.

Y ahora queremos borrar a todas las “Secretarias”. Pero si escribimos algo así:

DELETE FROM
   EMPLEADOS   E
JOIN
   PROFESIONES P
   ON E.EMP_IDEPRO = P.PRO_IDENTI
WHERE
   P.PRO_NOMBRE = 'Secretaria'

no funcionará. ¿Por qué no? porque el comando DELETE no tiene una cláusula JOIN que podamos usar. Entonces, ¿cómo hacemos para borrar a todas las “Secretarias”?

Reemplazando la cláusula JOIN por la función EXISTS(), como vemos a continuación:

Solución 1

DELETE FROM
   EMPLEADOS E
WHERE
   EXISTS(SELECT
             PRO_NOMBRE
          FROM
             PROFESIONES P
          WHERE
             E.EMP_IDEPRO = P.PRO_IDENTI AND
             P.PRO_IDENTI = 1)

Solución 2

DELETE FROM
   EMPLEADOS E
WHERE
   EXISTS(SELECT
             PRO_NOMBRE
          FROM
             PROFESIONES P
          WHERE
             E.EMP_IDEPRO = P.PRO_IDENTI AND
             P.PRO_NOMBRE = 'Secretaria')

En la Solución 1 usamos el identificador con el cual se referencian las tablas de EMPLEADOS y de PROFESIONES, mientras que en la Solución 2 usamos el nombre de la Profesión.

Con ambas soluciones se obtiene exactamente el mismo resultado, así que ya dependerá de tí cual de ellas te resulta más conveniente. En general, lo recomendable es que cuando se quiere borrar una fila se use el identificador de esa fila (o sea su Primary Key) y no alguna otra columna, es más seguro así.

Lo que debes notar es que en la cláusula WHERE que se encuentra dentro de la función EXISTS() debes escribir la misma condición que escribiste en el JOIN y además la condición que escribiste en el WHERE de tu SELECT. Es solamente eso, como ves, se soluciona muy fácilmente.

Pero siempre verifica que el resultado obtenido es exactamente el buscado antes de ejecutar tu COMMIT, porque si escribes mal el WHERE podrías llegar a borrar todas las filas de la tabla, no solamente algunas.

Conclusión:

Ni el comando INSERT, ni el comando UPDATE, ni el comando DELETE cuentan con una cláusula JOIN pero siempre podemos simular un INNER JOIN si usamos la función EXISTS().

Lo que debemos recordar es verificar que el resultado obtenido sea exactamente el buscado antes de ejecutar el COMMIT, porque si escribimos una mala condición en el WHERE podríamos estar afectando a muchas más filas de las que deberían, con resultados catrastróficos.

Artículo relacionado:

El índice del blog Firebird21