Respuestas:
La existspalabra clave se puede usar de esa manera, pero en realidad está destinada a evitar contar:
--this statement needs to check the entire table
select count(*) from [table] where ...
--this statement is true as soon as one match is found
exists ( select * from [table] where ... )
Esto es más útil cuando tiene ifdeclaraciones condicionales, ya que existspuede ser mucho más rápido que count.
Se inutiliza mejor cuando tiene que pasar una lista estática:
select * from [table]
where [field] in (1, 2, 3)
Cuando tiene una tabla en una indeclaración, tiene más sentido usar a join, pero sobre todo no debería importar. El optimizador de consultas debe devolver el mismo plan de cualquier manera. En algunas implementaciones (en su mayoría antiguas, como Microsoft SQL Server 2000), las inconsultas siempre obtendrán un plan de unión anidado , mientras que las joinconsultas usarán anidado, fusión o hash según corresponda. Las implementaciones más modernas son más inteligentes y pueden ajustar el plan incluso cuando inse usa.
select * from [table] where [field] in (select [field] from [table2])devuelve los mismos resultados (y plan de consulta) que select * from [table] join [table2] on [table2].[field] = [table].[field].
table, mientras que la segunda devuelve todo de tabley table2. En algunas bases de datos SQL (en su mayoría antiguas), la inconsulta se implementará como una unión anidada, mientras que la joinconsulta se puede anidar, fusionar, aplicar hash, etc., lo que sea más rápido.
existsse puede usar dentro de una declaración de caso, por lo que también pueden ser útiles de esa manera, es decirselect case when exists (select 1 from emp where salary > 1000) then 1 else 0 end as sal_over_1000
EXISTSle dirá si una consulta arrojó algún resultado. p.ej:
SELECT *
FROM Orders o
WHERE EXISTS (
SELECT *
FROM Products p
WHERE p.ProductNumber = o.ProductNumber)
IN se usa para comparar un valor con varios, y puede usar valores literales, como este:
SELECT *
FROM Orders
WHERE ProductNumber IN (1, 10, 100)
También puede usar los resultados de la consulta con la INcláusula, como esta:
SELECT *
FROM Orders
WHERE ProductNumber IN (
SELECT ProductNumber
FROM Products
WHERE ProductInventoryQuantity > 0)
Basado en el optimizador de reglas :
EXISTSes mucho más rápido que INcuando los resultados de la subconsulta son muy grandes.INes más rápido que EXISTScuando los resultados de la subconsulta son muy pequeños.Basado en el optimizador de costos :
Supongo que sabe lo que hacen y, por lo tanto, se usan de manera diferente, por lo que entenderé su pregunta como: ¿Cuándo sería una buena idea reescribir el SQL para usar IN en lugar de EXISTS, o viceversa?
¿Es eso una suposición justa?
Editar : La razón por la que pregunto es que, en muchos casos, puede reescribir un SQL basado en IN para usar EXISTS, y viceversa, y para algunos motores de base de datos, el optimizador de consultas tratará los dos de manera diferente.
Por ejemplo:
SELECT *
FROM Customers
WHERE EXISTS (
SELECT *
FROM Orders
WHERE Orders.CustomerID = Customers.ID
)
puede reescribirse a:
SELECT *
FROM Customers
WHERE ID IN (
SELECT CustomerID
FROM Orders
)
o con una combinación:
SELECT Customers.*
FROM Customers
INNER JOIN Orders ON Customers.ID = Orders.CustomerID
Entonces mi pregunta sigue en pie: ¿el póster original se pregunta qué hace IN y EXISTS y, por lo tanto, cómo usarlo, o pregunta si reescribir un SQL usando IN para usar EXISTS, o viceversa, será una buena idea?
JOIN, necesitarás unDISTINCT
EXISTSes mucho más rápido que INcuando los resultados de la subconsulta son muy grandes.
INes más rápido que EXISTScuando los resultados de la subconsulta son muy pequeños.
CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT)
GO
CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20))
GO
INSERT INTO t1
SELECT 1, 'title 1', 5 UNION ALL
SELECT 2, 'title 2', 5 UNION ALL
SELECT 3, 'title 3', 5 UNION ALL
SELECT 4, 'title 4', 5 UNION ALL
SELECT null, 'title 5', 5 UNION ALL
SELECT null, 'title 6', 5
INSERT INTO t2
SELECT 1, 1, 'data 1' UNION ALL
SELECT 2, 1, 'data 2' UNION ALL
SELECT 3, 2, 'data 3' UNION ALL
SELECT 4, 3, 'data 4' UNION ALL
SELECT 5, 3, 'data 5' UNION ALL
SELECT 6, 3, 'data 6' UNION ALL
SELECT 7, 4, 'data 7' UNION ALL
SELECT 8, null, 'data 8' UNION ALL
SELECT 9, 6, 'data 9' UNION ALL
SELECT 10, 6, 'data 10' UNION ALL
SELECT 11, 8, 'data 11'Consulta 1
SELECT
FROM t1
WHERE not EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id)
Consulta 2
SELECT t1.*
FROM t1
WHERE t1.id not in (SELECT t2.t1id FROM t2 )
Si en t1su identificación tiene un valor nulo, la Consulta 1 los encontrará, pero la Consulta 2 no puede encontrar los parámetros nulos.
Es decir IN, no puedo comparar nada con nulo, por lo que no tiene ningún resultado para nulo, pero EXISTSpuede comparar todo con nulo.
Si está utilizando el INoperador, el motor SQL escaneará todos los registros obtenidos de la consulta interna. Por otro lado, si estamos usando EXISTS, el motor SQL detendrá el proceso de escaneo tan pronto como encuentre una coincidencia.
IN solo admite relaciones de igualdad (o desigualdad cuando está precedido por NOT ).
Es un sinónimo de = any / = some , p. Ej.
select *
from t1
where x in (select x from t2)
;
EXISTS admite tipos de relaciones variantes, que no se pueden expresar con IN , por ejemplo:
select *
from t1
where exists (select null
from t2
where t2.x=t1.x
and t2.y>t1.y
and t2.z like '℅' || t1.z || '℅'
)
;
El supuesto rendimiento y las diferencias técnicas entre EXISTS e IN pueden ser el resultado de implementaciones / limitaciones / errores específicos del proveedor, pero muchas veces no son más que mitos creados debido a la falta de comprensión de las bases internas de las bases de datos.
La definición de las tablas, la precisión de las estadísticas, la configuración de la base de datos y la versión del optimizador tienen un impacto en el plan de ejecución y, por lo tanto, en las métricas de rendimiento.
La Existspalabra clave evalúa verdadero o falso, pero la INpalabra clave compara todos los valores en la columna de subconsulta correspondiente. Otro se Select 1puede usar con Existscomando. Ejemplo:
SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)
Pero INes menos eficiente y Existsmás rápido.
Yo creo que,
EXISTSes cuando necesita hacer coincidir los resultados de la consulta con otra subconsulta. Los resultados de la consulta n. ° 1 deben recuperarse donde coinciden los resultados de SubQuery. Tipo de unión ... Por ejemplo, seleccione la tabla n. ° 1 de los clientes que han realizado pedidos en la tabla n. ° 2
IN es recuperar si el valor de una columna específica se encuentra en INuna lista (1,2,3,4,5) Por ejemplo, seleccione clientes que se encuentran en los siguientes códigos postales, es decir, los valores de código postal se encuentran en la lista (...).
Cuándo usar uno sobre el otro ... cuando sienta que se lee apropiadamente (comunica mejor la intención).
La diferencia yace aquí:
select *
from abcTable
where exists (select null)
La consulta anterior devolverá todos los registros, mientras que la siguiente devolverá vacía.
select *
from abcTable
where abcTable_ID in (select null)
Pruébalo y observa la salida.
Cuál es más rápido depende del número de consultas obtenidas por la consulta interna:
EXIST evalúe en verdadero o falso pero IN compare el valor múltiple. Cuando no sabe que el registro existe o no, debe elegir EXIST
La razón es que el operador EXISTA funciona según el principio de "al menos encontrado". Devuelve verdadero y detiene la tabla de exploración una vez que se encuentra al menos una fila coincidente.
Por otro lado, cuando el operador IN se combina con una subconsulta, MySQL debe procesar la subconsulta primero y luego utiliza el resultado de la subconsulta para procesar toda la consulta.
La regla general es que si la subconsulta contiene un gran volumen de datos, el operador EXISTA proporciona un mejor rendimiento.
Sin embargo, la consulta que utiliza el operador IN se realizará más rápido si el conjunto de resultados devuelto por la subconsulta es muy pequeño.
Entiendo que ambos deberían ser iguales siempre y cuando no estemos tratando con valores NULL.
La misma razón por la cual la consulta no devuelve el valor para = NULL vs es NULL. http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/
En cuanto al argumento booleano vs comparador, para generar un valor booleano, ambos valores deben compararse y así es como funciona la condición if.Así que no entiendo cómo IN y EXISTS se comportan de manera diferente.
In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.
https://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm#i28403
Si una subconsulta devuelve más de un valor, es posible que deba ejecutar la consulta externa, si los valores dentro de la columna especificada en la condición coinciden con cualquier valor en el conjunto de resultados de la subconsulta. Para realizar esta tarea, debe usar la inpalabra clave.
Puede usar una subconsulta para verificar si existe un conjunto de registros. Para esto, debe usar la existscláusula con una subconsulta. La existspalabra clave siempre devuelve un valor verdadero o falso.
Creo que esto tiene una respuesta directa. ¿Por qué no lo compruebas de las personas que desarrollaron esa función en sus sistemas?
Si usted es un desarrollador de MS SQL, aquí está la respuesta directamente de Microsoft.
IN:
Determina si un valor especificado coincide con algún valor en una subconsulta o una lista.
Especifica una subconsulta para probar la existencia de filas.
Descubrí que usar la palabra clave EXISTS a menudo es muy lento (eso es muy cierto en Microsoft Access). En su lugar, uso el operador de combinación de esta manera: should-i-use-the-keyword-exist-in-sql
EXISTE es más rápido en rendimiento que IN. Si la mayoría de los criterios de filtro están en subconsulta, entonces es mejor usar IN y si la mayoría de los criterios de filtro están en la consulta principal, mejor usar EXISTS.
Si está utilizando el operador IN, el motor SQL escaneará todos los registros obtenidos de la consulta interna. Por otro lado, si estamos usando EXISTS, el motor SQL detendrá el proceso de escaneo tan pronto como encuentre una coincidencia.
INy EXISTSpueden ser equivalentes y transformados entre sí.
JOINcomo reemplazoIN.