So,
I want a SQL Query where I can enforce an object having multiple associations
So i want to query all videos where they have all the tags i am limiting on
So Video must have a videos_tags that associates it to tags.id 1,2 and 3
so far I tried
SELECT videos.*, tags_videos.tag_id, tags_videos.video_id FROM videos
LEFT JOIN tags_videos ON tags_videos.video_id = videos.id
WHERE tags_videos.tag_id IN (1,2,3)
but this seems to be more of an OR clause not an AND clause is there and Exclusive and IN statement?
Also this is in Rails with active record. Is there a way to do this easily via AR in Rails?
Heres what i’ve tried
Video.all.select{|v| params[:tags].select{|t| v.tag_ids.include?(t.to_i)}.count == params[:tags].count }
If you want videos which have tags 1,2 and 3, envision what a result row would need to look like. You’ll realise you’ll need one column for each tag. To do this, you’ll need to join against tags_videos once for each tag you want to match.
I’ve also used INNER JOIN rather then LEFT JOIN as you’re not interested in any that don’t match.
Conceptually, you can think of this query as first getting all the videos which have tag 1, and then seeing which of those also have tag 2. So now we have videos with tag1+2, we can see which of those also have tag3. You can keep going for as many tags as you need.
While I doubt it applies to your situation, one alternative method would to use a SET column type to store all the tags for a video, but this would only allow for 64 different tags. The advantage is that this column could be stored in the videos table, and thus a join would not be required (you’d just have a WHERE clause using FIND_IN_SET multiple times)