开发者

finding records with join on multiple relation tables

I have 3 tables.

  1. Tour Table (optional)
  2. Tour Tag Relation Table (optional_tag_rel)
  3. Tour Theme Relation Table (optional_theme_rel)

A tour can have multiple tags and multiple themes. So I what to write and sql statement to find specified tours. For example find tours where tag id = 10 and 15 and theme id = 36 and 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 t开发者_运维问答2.tag_id =15) 
GROUP BY optional.id 

These statement gets all records whose theme id = 36 or 45, but I need to use AND statement but when I use AND instead of OR, it shows no record. There has to be different way of doing this on sql but I dont know much about it.


If I understand correctly that you want tours that have both themes (with theme_id =36 and 45) and both tags (with tag_id=10 and 15), then you neither need the GROUP BY nor the DISTINCT.

But one way to do this is to join twice to each one of the secondary tables:

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

Another way to get same results is:

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


  • Use the IN syntax
  • no need for the group by (you have no aggregate functions in play)
  • the placement of your AS was slightly out

Try this:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜