How do I efficiently do the intersection of joins in SQL? -
i have 3 tables, books, tags, , taggings (books-xref-tags):
books id | title |      author       1 | blink | malcolm gladwell  2 |  1984 |    george orwell  taggings book_id | tag_id       1 |      1       1 |      2       2 |      1       2 |      3  tags id | name  1 | interesting  2 |  nonfiction  3 |     fiction   i'd search books tagged both "interesting" and "fiction." best i've come is
select books.* books, taggings, tags  taggings.book_id = books.id    , taggings.tag_id  = tag.id    , tag.name = "interesting" intersect select books.* books, taggings, tags  taggings.book_id = books.id    , taggings.tag_id  = tag.id    , tag.name = "fiction"   that seems work, i'm not sure how scale, either in rows or number of tags. is, happens add hundreds of books, hundreds of tags, , thousands of taggings? happens search becomes "'interesting' and 'fiction' and 'aquatic' and 'stonemasonry'"?
i have alternative approach in mind if there's no better way of doing query directly in sql:
- select books first tag, along of books' tags
 - remove list don't have of tags queried
 
if want keep option of using more 2 tags, this answer similar interesting you.
it uses mysql syntax (not sure use), quite simple , should able use other databases.
this (using mysql syntax):
select books.id, books.title, books.author books inner join taggings on ( taggings.book_id = books.book_id ) inner join tags on ( tags.tag_id = taggings.tag_id ) tags.name in ( @tag1, @tag2, @tag3 ) group books.id, books.title, books.author having count(*) = @number_of_tags   from other post:
if have 3 tags in example number_of_tags have 3, , join result in 3 rows per id matches.
you can either create query dynamically, or define with, say, 10 tags , initialize them value won't occur in tags.
Comments
Post a Comment