SELECCIONAR * DONDE NO EXISTE

94

Creo que voy por el camino correcto con este ... Por favor, tengan paciencia conmigo ya que mi SQL no es el mejor

Estoy tratando de consultar una base de datos para seleccionar todo de una tabla donde ciertas celdas no existen en otra. Eso no tiene mucho sentido, pero espero que este fragmento de código

SELECT * from employees WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

Básicamente, tengo una tabla con una lista de empleados y sus detalles. Luego otra tabla con algunos otros detalles, incluido su nombre. Donde no hay nombre en la tabla eotm_dyn, lo que significa que no hay una entrada para ellos, me gustaría ver exactamente quiénes son, o en otras palabras, ver qué falta exactamente.

La consulta anterior no devuelve nada, pero sé que faltan 20 nombres, así que obviamente no lo he hecho bien.

¿Alguien puede ayudar?

Ciaran
fuente

Respuestas:

160

No se unió a la mesa en su consulta.

Su consulta original siempre no devolverá nada a menos que no haya registros en absoluto eotm_dyn, en cuyo caso devolverá todo.

Suponiendo que estas tablas deben unirse employeeID, use lo siguiente:

SELECT  *
FROM    employees e
WHERE   NOT EXISTS
        (
        SELECT  null 
        FROM    eotm_dyn d
        WHERE   d.employeeID = e.id
        )

Puede unir estas tablas con una LEFT JOINpalabra clave y filtrar las NULL's, pero es probable que esto sea menos eficiente que usar NOT EXISTS.

Quassnoi
fuente
30
Necesito "DONDE NO EXISTE" dos veces al año, y siempre olvido cómo usarlo exactamente. Gracias, este ejemplo se marcará ahora.
Mateng
1
¿Podría alguien dar una referencia para que "LEFT JOIN + NULL filter es menos eficiente que NO EXISTS"? Puede ser obvio, pero nunca vi eso en los documentos. Gracias.
toni07
2
@ toni07 En realidad, eso es una leyenda. LEFT JOIN gana. explainextended.com/2009/09/18/… .. El blog de Quassnoi es siempre un recurso útil.
Kaii
¿Cómo usaría esto en una cláusula HAVING? akagroup by X having exist [row with employeeID = e.id]
phil294
@blauhirn: así como así
Quassnoi
83
SELECT * FROM employees WHERE name NOT IN (SELECT name FROM eotm_dyn)

O

SELECT * FROM employees WHERE NOT EXISTS (SELECT * FROM eotm_dyn WHERE eotm_dyn.name = employees.name)

O

SELECT * FROM employees LEFT OUTER JOIN eotm_dyn ON eotm_dyn.name = employees.name WHERE eotm_dyn IS NULL
Día de Robin
fuente
1
¡NÓTESE BIEN! NOT INno funciona como se esperaba si nametiene nullvalores. Mire desde 36min 20seg en el video SESIÓN: 10 técnicas de ajuste de consultas que todo programador de SQL debe conocer (Kevin Kline, Aaron Bertrand) .
hlovdal
12

Puede hacer una LEFT JOIN y afirmar que la columna unida es NULL.

Ejemplo:

SELECT * FROM employees a LEFT JOIN eotm_dyn b on (a.joinfield=b.joinfield) WHERE b.name IS NULL
Mike Tunnicliffe
fuente
7
SELECT * from employees
WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

Nunca devuelve ningún registro a menos que eotm_dynesté vacío. Necesitas algún tipo de criterio sobre SELECT name FROM eotm_dyncomo

SELECT * from employees
WHERE NOT EXISTS (
    SELECT name FROM eotm_dyn WHERE eotm_dyn.employeeid = employees.employeeid
)

asumiendo que las dos tablas están vinculadas por una relación de clave externa. En este punto, puede usar una variedad de otras opciones, incluida una LEFT JOIN. Sin embargo, el optimizador normalmente los manejará de la misma manera en la mayoría de los casos.

Cade Roux
fuente
4

También puede echar un vistazo a esta pregunta relacionada . Ese usuario informó que usar una combinación proporciona un mejor rendimiento que usar una subconsulta.

Andre Miller
fuente