Disons que nous avons une table (EnsembleMembers) dans une base de données SQL avec les données suivantes. Il répertorie les musiciens qui font partie de différents ensembles, ainsi que leurs instruments.Problème avec requête SQL impliquant une condition de type XOR
EnsembleID (FK) MusicianID (FK) Instrument
----------------------------------------------
'1' '1' 'Clarinet'
'1' '4' 'Clarinet'
'1' '100' 'Saxophone'
'2' '200' 'Saxophone'
'2' '300' 'Saxophone'
'2' '320' 'Flute'
'99' '300' 'Clarinet'
Je veux sélectionner les ID d'ensemble où l'ensemble a un ou plusieurs saxophone ou un ou plusieurs joueurs de clarinette, mais pas les deux. J'ai essayé l'instruction SQL suivante, mais elle renvoie 1,2,2,99
, plutôt que le 2,99
attendu.
SELECT e1.EnsembleID
FROM ensemblemembers e1
WHERE e1.Instrument = 'Saxophone'
OR e1.Instrument = 'Clarinet'
AND NOT EXISTS (SELECT *
FROM ensemblemembers e2
WHERE ( e1.Instrument = 'Saxophone'
AND e2.Instrument = 'Clarinet'
AND e1.EnsembleID = e2.EnsembleID)
OR ( e1.Instrument = 'Clarinet'
AND e2.Instrument = 'Saxophone'
AND e1.EnsembleID = e2.EnsembleID));
Qu'est-ce que je fais mal? PS - Je ne souhaite pas utiliser DISTINCT pour des raisons de performances.
SANS utiliser DISTINCT? –
Dans la solution GROUP BY, vous devez utiliser DISTINCT s'il peut y avoir plusieurs saxophones ou plusieurs clarinettes dans un ensemble. Voir aussi la deuxième solution que je viens d'ajouter, qui peut fonctionner en fonction de la marque de base de données que vous utilisez. –
Etes-vous sûr que l'exemple de jointure externe complète est correct? Je sais que MySQL ne les supporte pas mais j'ai dupliqué votre exemple, changé l'un en jointure externe gauche, l'autre en jointure externe droite, et union'd les deux (ce qui est le moyen d'émuler la fonctionnalité AFAIK), mais je l'ai toujours récupéré un ensemble d'identification d'un ensemble ayant à la fois un saxophone et un clarinettiste. –