Inner Join et multicritères

Inner Join et multicritères - SQL/NoSQL - Programmation

Marsh Posté le 15-05-2006 à 17:16:30    

Yop all,je voyais pas du tout comment nommer correctement ce post :p
Le problème de base est une jointure, mais ce que j'aimerais récupérer est un peu particulier, je m'explique :  
 
Imaginons la table 1, avec un champ ID
Imaginons la table 2, avec un champ ID (qui correspond à l'ID de la table 1, une FK quoi), et un champ valeur
 
Je souhaite récupérer tous les enregistrements de la table 1 satisfaisant simultanément plusieurs conditions de valeur dans la table 2.
 
Exemple :  
Table 1 :  
1 enregistrement : ID = 1
 
Table 2 :  
1er enregistrement : ID = 1, valeur = 1
2eme enregistrement : ID = 1, valeur = 2
 
je souhaite récupérer les enregistrements de la table 1 qui possèdent la valeur 1 et la valeur 2 dans la table 2.
Si je fais ça :  

Code :
  1. select * from table1 as t1
  2. inner join table2 as t2
  3. on t1.id = t2.id
  4. where t2.valeur = 1 and t2.valeur = 2


je ne récupère rien.
 
SI je fais ça :

Code :
  1. select * from table1 as t1
  2. inner join table2 as t2
  3. on t1.id = t2.id
  4. where t2.valeur = 1 or t2.valeur = 2


je vais récupérer les enregistrements qui n'ont que valeur égal à 1, ou que valeur = 2.
Moi je veux les enregistrements qui ont leurs valeur égale à 1 et à 2.
 
J'ai donc trouvé ça :  

Code :
  1. select * from table1 as t1
  2. inner join table2 as t2
  3. on t1.id = t2.id
  4. inner join table2 as t3
  5. on t1.id = t3.id
  6. where  t2.valeur = 1 and t3.valeur = 2


Là très bien ça marche, mais .... une jointure par critère, c'est abusif. Si j'ai 20 critères de recherche, je vais pas faire 20 jointures ....
 
Y a un autre moyen de faire ça ?
A vot'bon coeur m'sieur dame !


Message édité par Djebel1 le 15-05-2006 à 17:20:12
Reply

Marsh Posté le 15-05-2006 à 17:16:30   

Reply

Marsh Posté le 15-05-2006 à 17:57:53    

tu peux aussi l'écrire comme ça :
 

Code :
  1. select *
  2.   from table1
  3. where
  4.          exists (select 1 from table2 where table2.id = table1.id and valeur = 2)
  5. and    exists (select 1 from table2 where table2.id = table1.id and valeur = 1)


 
le 1 dans select 1 est une info inutile, c'est juste pour vérifier la validité du select, tu peux donc mettre n'importe quoi mais quoiqu'il en soit tu seras obligé de vérifier (exists) pour chaque valeur que tu veux rajouter...
 

Reply

Marsh Posté le 15-05-2006 à 18:10:39    

donc dans tous les cas, soit je fais une jointure par critère de recherche, soit je fais une sous-requête par critère de recherche.
Les sous-requêtes boufferont moins non ?

Reply

Marsh Posté le 15-05-2006 à 18:34:35    

ok bah merci bcp de ton aide, ta solution marche au poil, la mienne est dans les choux et plante allègrement la base :p


Message édité par Djebel1 le 15-05-2006 à 18:34:52
Reply

Marsh Posté le 15-05-2006 à 19:03:04    

ta solution devrait aussi bien marcher normalement, c'est bizarre qu'elle te plante ta base.
 
la mienne devrait être plus performante je pense mais ca dépend bcp de la volumétrie de table1 et de table2 ainsi que de l'existence d'un index sur id.
 
si table2 est toute petite, qu'il y a un index sur l'id de table1, et que table1 est énorme, ta requête sera plus rapide à mon avis et encore tout dépend du sgbd et du plan généré.
 
c'est dur à savoir par avance, une seule solution le test ;)

Reply

Marsh Posté le 15-05-2006 à 19:52:50    

je suis également assez étonné que la solution par jointure rame autant, j'ai fait un test à l'arrache avec 100 enregistrements dans table1, 2 dans table2, aucun index nul part, et 20 critères (donc 20 jointures ou 20 sous-requêtes selon la solution utilisée). La requete par jointure a planté la base :/
La requête par sous-requêtes a abouti en 0,03 s.


Message édité par Djebel1 le 15-05-2006 à 19:53:46
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed