Résultats de requête SQL IN () générant des résultats indésirables

Juste besoin d'aide pour affiner cette requête si possible.

SELECT * FROM E_Associates INNER JOIN E_Tag_Atsortingbutes ON E_Tag_Atsortingbutes.AssociateID = E_Associates.associateID WHERE (TagID IN (524,546)) AND CONTAINS ((AboutMe,WorkingStyle,Approach,MyValues),'werwer') AND IsActive = 1 

Fondamentalement, j'ai trois tables …

E_associates qui est un nom de table de contacts etc …

E_Tag_Atsortingbutes qui est une table de binding entre la table E_associates et E_associates .

Je souhaite afficher uniquement les users ayant à la TagID les TagID 524 et 546 dans les E_Tag_Atsortingbutes

Cette requête produit cependant des résultats qui ont un ou les deux …

Très fatigué, j'espère que c'est quelque chose de simple 🙂

Merci d'avance.

La clause SQL IN () se combinera par OR et non par AND.

 (...) WHERE A IN ( 1, 2, 3 ) 

est équivalent à

 (...) WHERE ( A = 1 OR A = 2 OR A = 3 ) 

Dans ce cas, vous devrez joindre deux fois la même table et déplacer la clause TagID dans les critères de jointure:

 SELECT * FROM E_Associates EA INNER JOIN E_Tag_Atsortingbutes J1 ON J1.AssociateID = EA.associateID AND TagId = 524 INNER JOIN E_Tag_Atsortingbutes J2 ON J2.AssociateID = EA.associateID AND TagId = 526 WHERE CONTAINS ((AboutMe,WorkingStyle,Approach,MyValues),'werwer') AND IsActive = 1 

Je ne suis pas sûr que la clause WHERE fonctionnera de cette façon. Si les colonnes sont définies dans les tables E_Tag_Atsortingbutes, vous risquez d'avoir des problèmes de colonne «ambigus». Si c'est le cas, mettez simplement les clauses dans les critères de jointure et mettez un J1. ou J2. si nécessaire.

En supposant que vous voulez tous les associés qui ont des labels 524 et 546:

 SELECT * FROM E_Associates INNER JOIN E_Tag_Atsortingbutes e1 ON e1.AssociateID = E_Associates.associateID INNER JOIN E_Tag_Atsortingbutes e2 ON e2.AssociateID = E_Associates.associateID WHERE (e1.TagID IN (524)) AND CONTAINS ((AboutMe,WorkingStyle,Approach,MyValues),'werwer') AND (e2.TagID IN (546)) AND CONTAINS ((AboutMe,WorkingStyle,Approach,MyValues),'werwer') AND IsActive = 1 

L'utilisation de la clause IN() spécifie qu'il doit searchr les loggings ayant l'une des valeurs spécifiées. Donc, il va faire ce que vous avez décrit.

Si vous souhaitez searchr uniquement ceux pour lesquels il existe un logging associé pour les deux valeurs spécifiées, vous devrez le faire dans les jointures.

Vous pouvez append le champ TagId à la clause ON de la jointure, exactement comme dans une clause WHERE ; juste parce que c'est dans la clause ON , il n'a pas besoin de spécifier un champ liant directement à la table principale. Cependant, dans ce cas, utiliser IN() ici aura le même effet que dans la clause WHERE , donc nous devons aller plus loin …

Pour find les deux valeurs liées à chaque logging E_Associates , vous devez joindre deux fois la table E_Tag_Atsortingbutes :

 SELECT * FROM E_Associates INNER JOIN E_Tag_Atsortingbutes ta1 ON ta1.AssociateID = E_Associates.associateID AND ta1.TagId = 524 INNER JOIN E_Tag_Atsortingbutes ta2 ON ta2.AssociateID = E_Associates.associateID AND ta2.TagId = 526 WHERE CONTAINS ((AboutMe,WorkingStyle,Approach,MyValues),'werwer') AND IsActive = 1 

Notez que j'ai dû append des alias ( ta1 et ta2 ) pour les deux jointures E_Tag_Atsortingbutes , pour éviter les ambiguïtés dans la requête puisque le nom de la table est le même pour les deux.

Une autre option que vous pouvez envisager est d'interroger en utilisant IN() comme vous le faites déjà, mais d'utiliser GROUP BY AssociateID , et d'append une clause WHERE telle que COUNT(TagId)=2 . Cela filterra les résultats de sorte que seuls ceux qui ont deux balises dans le jeu de résultats seront inclus.