Pregunta

Tengo una tabla de índice de muchos a muchos, y quiero hacer una consulta de tipo incluir / excluir en ella.

fid es realmente un índice entero, pero aquí como letras para una comprensión más fácil. Aquí hay una tabla de muestra:

tabla t

eid | fid
----+----
1   | A
1   | B
1   | C
2   | B
2   | C
3   | A
3   | C
4   | A
4   | B
5   | B

Aquí hay algunas consultas de muestra que quiero.

  1. ¿Qué eids tienen fid B y NO A? (Responda eid 2 y 5)
  2. ¿Qué eids tienen fid C y NO A? (Respuesta eid 2)

Parece que no puedo resolver una consulta que haga esto.

He intentado una autounión como esta:

select * 
from t as t1 
join t as t2 
where t1.eid=t2.eid 
  and t1.fid!=t2.fid 
  and t1.fid=B and t2.fid!=A

Eso no funcionará, porque aún devolverá filas donde eid = 1 y fid = C.

¿Tengo claro lo que quiero?

¿Fue útil?

Solución

Aquí hay un ejemplo de una consulta para 1 (2 funciona de la misma manera)

select t1.eid
  from t t1
 where t1.fid  = 'B'
   and not exists
       (select 1
          from t t2
         where t2.eid = t1.eid
           and t2.fid  = 'A')

Otros consejos

Use establezca la resta

Select eid from t where fid = 'B' 
EXCEPT
select eid from t where fid = 'A'

Puedes usar una sub-selección

seleccione eid desde t donde fid = 'C' y eid no está dentro (seleccione eid desde t donde fid = 'A')

MySQL 5.0 admite dónde existe / dónde no existe, según lo descrito por Nigel y Mike.

Versión con combinaciones directas que puede ser más rápida que usar EXISTS:

Select  t1.eid
From    #test t1
        left join (
            Select  eid
            From    #test t2 
            Where   fid = 'A'
            Group by eid
        ) t2 on t2.eid = t1.eid 
Where   t1.fid = 'B'
        and t2.eid is null

Debería ser posible hacer esto sin usar una subconsulta:

SELECT DISTINCT t1.eid
FROM table1 AS t1
  LEFT JOIN table1 AS t2 ON (t1.eid = t2.eid AND t2.fid = 'A')
WHERE t2.eid IS NULL
  AND t1.fid = 'B';

Para hacer su segunda búsqueda de ejemplo, simplemente cambie el valor 'B' a 'C'.

Mire en el operador MENOS. Funciona como UNION, excepto que resta donde UNION agrega. La respuesta anterior con la palabra "EXCEPTO" puede ser una palabra clave diferente para la misma cosa.

Aquí hay una respuesta no probada:

select eid 
from t
where fid = 'A'
minus
select eid
from t
where fid = 'B'
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top