开发者

Having some trouble trying to filter results returned from PostgreSQL based on certain IDs

Due to boredom, I decided to setup a simple tagging system for my movies today. I basically have a list of movie titles and X number of tags for each movie. The database looks like this:

mydb=# select id, title from movies;

 id |                  title                   
----+----------------------------------------
  1 | first_movie
  2 | second_movie

mydb=# select id, movie_id, tag_id from movie_tags;

 id | movie_id | tag_id 
----+----------+--------
  1 |        1 |    716
  2 |        1 |    787
  3 |        1 |    322
  4 |        2 |    716
  5 |        2 |    787
  6 |        2 |    323

mydb=# SELECT l.id, l.title, t.tag_id FROM movies l, movie_tags t WHERE t.movie_id = l.id AND t.tag_id IN(7开发者_JS百科16, 787, 323);

 id |    title     | tag_id 
----+--------------+--------
  2 | second_movie |    787
  2 | second_movie |    716
  2 | second_movie |    323
  1 | first_movie  |    716
  1 | first_movie  |    787

It's the third query that's causing me problems. Firstly, it's showing duplicate rows. A new row for each tag_id. I don't want this. I'd prefer it to show one row, for each movie, that matches the specified tags.

Which leads me to the second problem. As you can see, first_movie isn't tagged with tag_id=323. However, it still shows up in the results.

How can I not show duplicate rows and filter the results to movies that match all the given tags?

I planned on building a simple UI for this so I was hoping for a nice 'dynamic' query that I can drop a list of tag_ids into.


This query gives you all movies that have all 3 of the tags searched.

  SELECT l.id, l.title
    FROM movies l, movie_tags t
   WHERE t.movie_id = l.id
     AND t.tag_id IN (716, 787, 323)
GROUP BY l.id, l.title
  HAVING COUNT(*) = 3

As you can see, the tag column is removed because it doesn't make sense to include one arbitrary tag.


SELECT l.id, l.title
FROM movies l
WHERE l.id IN (SELECT t.movie_id 
               FROM movie_tags t 
               WHERE t.tag_id IN (716, 787, 323));
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜