El operador EXISTS de SQL nos ofrece una manera sencilla de recuperar datos en función de la existencia (o no existencia) de otros datos. Más específicamente, es un operador lógico que evalúa los resultados de una subconsulta y devuelve un valor booleano que indica si se devolvieron filas o no. Si bien el operador IN se puede utilizar para el mismo propósito, existen algunas diferencias que se deben tener en cuenta. El blog de hoy cubrirá cómo usar el operador EXISTS mediante algunos ejemplos y también brindará algunas pautas sobre cuándo usar EXISTS en lugar de IN.
EXISTS en acción
Si bien el operador EXISTS se puede usar en una declaración SELECT, UPDATE, INSERT o DELETE, nos quedaremos con las consultas SELECT para simplificar las cosas. Por lo tanto, la sintaxis que usaremos se parecerá mucho a esta:
SELECT column_name(s) FROM table_name WHERE EXISTS ( SELECT column_name(s) FROM table_name WHERE condition );
Ejecutaremos nuestras consultas en un par de tablas PostgreSQL (cliente y cuenta), como las que podríamos encontrar en una base de datos bancaria. Aquí están en Navicat para la vista de cuadrícula de PostgreSQL:
Ahora podemos ver todos los clientes que tienen una cuenta asociada con su customer_id mediante la siguiente consulta:
SELECT * FROM customer C WHERE EXISTS ( SELECT * FROM account A WHERE C.customer_id = A.customer_id );
A continuación se muestra la consulta anterior con los resultados en el Editor de consultas de Navicat Premium:

Uso de NOT con EXISTS
Por el contrario, anteponer al operador EXISTS la palabra clave NOT hace que la consulta solo seleccione registros en los que no haya ninguna fila coincidente en la subconsulta. Podemos usar NOT EXISTS para recuperar todas las cuentas huérfanas, es decir, las cuentas sin ningún cliente asociado:
SELECT * FROM account A WHERE NOT EXISTS ( SELECT * FROM customer C WHERE A.customer_id = C.customer_id );
Eso devuelve la cuenta del cliente n.° 4, ya que no hay ningún cliente con esa identificación en la tabla de clientes.

Reemplazo de EXISTS con uniones
Las consultas que utilizan el operador EXISTS pueden ser un poco lentas de ejecutar porque la subconsulta debe ejecutarse para cada fila de la consulta externa. Por ese motivo, debe considerar el uso de uniones siempre que sea posible. De hecho, podemos reescribir la consulta EXISTS anterior utilizando un LEFT JOIN:
SELECT C.* FROM customer C LEFT JOIN account A ON C.customer_id = A.customer_id;

Operadores IN vs EXISTS
Aunque el operador IN se utiliza normalmente para filtrar una columna en función de una determinada lista de valores, también se puede aplicar a los resultados de una subconsulta. Este es el equivalente a nuestra primera consulta, esta vez utilizando IN en lugar de EXISTS:
SELECT * FROM customer WHERE customer_id IN (SELECT customer_id FROM account);
Tenga en cuenta que solo podemos seleccionar la columna con la que queremos realizar la comparación, a diferencia de SELECT *. No obstante, la consulta IN produce los mismos resultados:

Como ambos operadores son tan similares, los desarrolladores de bases de datos a menudo no saben cuál usar. Como regla general, debe usar el operador IN cuando desee filtrar filas en función de una lista específica de valores. Use EXISTS cuando desee verificar la existencia de filas que cumplan ciertas condiciones en una subconsulta.
Conclusión
En el blog de hoy aprendimos a usar el operador EXISTS y también a decidir si usar EXISTS o IN.
¿Está interesado en probar Navicat Premium 17? Puede descargarlo para una prueba GRATUITA completamente funcional de 14 días FREE trial. Está disponible para los sistemas operativos Windows, macOS y Linux.