2011-06-28 4 views
0

J'ai 3 tables.recherche d'enregistrements avec jointure sur plusieurs tables de relations

  1. tour de table (en option)
  2. tour Tag Relation table (optional_tag_rel)
  3. tour de table Thème Relation (optional_theme_rel)

Une visite peut avoir plusieurs balises et des thèmes multiples. Donc, je quoi écrire et sql déclaration pour trouver des visites spécifiées. Par exemple trouver des visites où id tag = 10 et 15 et le thème id = 36 et 45.

SELECT DISTINCT (t1.id) FROM optional AS t1 
LEFT JOIN optional_theme_rel as t3 ON t3.tour_id = t1.id AND (t3.theme_id =36 OR t3.theme_id =45) 
LEFT JOIN optional_tag_rel as t2 ON t2.tour_id = t1.id AND (t2.tag_id = 10 OR t2.tag_id =15) 
GROUP BY optional.id 

Ces déclaration obtient tous les enregistrements dont le thème id = 36 ou 45, mais je dois utiliser instruction AND mais quand je l'utilise ET au lieu de OU, il ne montre aucun enregistrement. Il doit y avoir une façon différente de faire cela sur sql mais je ne sais pas grand-chose à ce sujet.

Répondre

0

Si je comprends bien que vous voulez des visites h ave les deux thèmes (avec theme_id = 36 et 45) et les deux tags (avec tag_id = 10 et 15), alors vous n'avez pas besoin du GROUP BY ni du DISTINCT.

Mais une façon de le faire est de se joindre deux fois à chacune des tables secondaires:

SELECT op.id 
FROM optional AS op 

    JOIN optional_theme_rel AS theme1 
    ON theme1.tour_id = op.id 
    AND theme1.theme_id = 36 
    JOIN optional_theme_rel AS theme2 
    ON theme2.tour_id = op.id 
    AND theme2.theme_id = 45 

    JOIN optional_tag_rel AS tag1 
    ON tag1.tour_id = op.id 
    AND tag1.tag_id = 10 
    JOIN optional_tag_rel AS tag2 
    ON tag2.tour_id = op.id 
    AND tag2.tag_id = 15 

Une autre façon d'obtenir même résultat est:

SELECT op.id 
FROM optional AS op 

    JOIN 
    (SELECT tour_id 
     FROM optional_theme_rel 
     WHERE theme_id IN (36, 45) 
     GROUP BY tour_id 
     HAVING COUNT(DISTINCT theme_id) = 2 
    ) AS theme 
    ON theme.tour_id = op.id 

    JOIN 
    (SELECT tour_id 
     FROM optional_tag_rel 
     WHERE tag_id IN (10, 15) 
     GROUP BY tour_id 
     HAVING COUNT(DISTINCT tag_id) = 2 
    ) AS tag 
    ON tag.tour_id = op.id 
+0

Cela fonctionne. Je cherchais cette réponse pour quelques jours. J'ai besoin d'étudier les déclarations mysql. Merci encore. – dorayaki

0
  • Utilisez la syntaxe IN
  • pas besoin de l'group by (vous n'avez pas des fonctions d'agrégation en jeu)
  • le placement de votre AS était légèrement hors

Essayez ceci:

SELECT DISTINCT t1.id 
FROM optional t1 
LEFT JOIN optional_theme_rel as t3 ON t3.tour_id = t1.id AND t3.theme_id in (36, 5) 
LEFT JOIN optional_tag_rel as t2 ON t2.tour_id = t1.id AND t2.tag_id in (10, 15) 
+1

grâce - a ajouté ce . Je pense que cette réponse est fausse de toute façon - dépend de ce que la question demande. il n'est pas clair si il veut les deux ou – Bohemian

+0

Merci pour la réponse, cette déclaration me donne les mêmes résultats que dans ma requête. Je pense que je ferais mieux de vérifier ma grammaire deux fois. En tout cas, merci pour votre aide. – dorayaki

Questions connexes