2008-09-24 7 views
2

J'ai une table d'index plusieurs à plusieurs, et je veux faire une requête de type include/exclude. Fid est vraiment un index entier, mais ici comme des lettres pour une meilleure compréhension. Voici un exemple de table:Plusieurs à plusieurs requêtes de table

table t

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

Voici quelques exemples de requêtes que je veux.

  1. De quoi les Eids ont-ils la valeur B, et NON A? (Réponse eid 2 et 5)
  2. Quels eids ont fid C et NOT A? (Réponse eid 2)

Je n'arrive pas à trouver une requête qui va le faire.

J'ai essayé une jointure réflexive comme ceci:

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 

Cela ne fonctionnera pas, car il retournera encore les lignes où eid = 1 et fid = C.

Suis-je clair sur ce que je veux?

Répondre

3

Voici un exemple de requête pour 1 (2 fonctionne à peu près de la même façon)

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') 
+0

merci, cela a fonctionné dans mysql – Pyrolistical

7

Utilisez set subtraction

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

Grande pointe; En fait, je n'ai jamais utilisé la syntaxe EXCEPT. –

1

Vous pouvez utiliser un sous-select

select eid de t où fid = 'C' et eid pas (sélectionnez eid de t où fid = 'A')

0

MySQL 5.0 prend en charge l'endroit où existe/n'existe pas, comme décrit par Nigel et Mike.

0

Version avec droit rejoint qui peut être plus rapide que d'utiliser EXISTE:

 
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 
0

Il devrait être possible de le faire sans utiliser une sous-requête:

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'; 

Pour votre deuxième exemple de recherche, juste changez la valeur 'B' en 'C'.

0

Regardez dans l'opérateur MINUS. Cela fonctionne comme UNION, sauf qu'il soustrait où UNION ajoute. La réponse précédente avec le mot "SAUF" peut être un mot-clé différent pour la même chose.

est ici une réponse non testé:

select eid 
from t 
where fid = 'A' 
minus 
select eid 
from t 
where fid = 'B' 
Questions connexes