繁体   English   中英

在一个表中选择与另一个表中的ID至少匹配的所有ID

[英]Select all ids in one table that match at least as many ids in another table

如果我有这样的表结构

[movies]---<[movies_genres]>---[genres]---<[users_genres]>---[users]

给定一个user.id ,我想查询仅与users_genres.genre_id共享其类型的users_genres.genre_id

更清楚的是,如果用户喜欢{科幻,动作和浪漫片}类型,而电影是{科幻,动作和恐怖片},则不应退还该电影。 但是,如果电影只是{sci-fi}或{sci-fi,动作},则应将其返回。 因此,如果其流派未在用户的首选流派中列出,则不应将其退回。

我该怎么做呢?

谢谢。

编辑:

我尝试过的东西

select movies_id from movies_genres mg
    where mg.genres_id not in (
    select genres_id from users_genres ug 
        where ug.users_id = 1
    )

编辑2:

好的,我已经修复了上面的代码,我认为它似乎可以正常工作

select * from movies 
where movies.id not in (
    select movies_id from movies_genres mg
    where mg.genres_id not in (
        select genres_id from users_genres ug 
            where ug.users_id = 2
        )
)

我基本上是在玩减集(我认为)。 这对我来说都是很新的,所以我什至不清楚SQL在这里是如何工作的。 就是这样,如果我可以从另一个中减去一个集合,结果结果是空的,那是一个子集。 这基本上满足了我对movie_genres作为users_genres的子集的要求。

一个joinaggregation应在表之间的工作:

select mg.movie_id
from user_genres ug left join
     movie_genres mg
     on mg.genre_id = ug.genre_id
where ug.user_id = ?
group by mg.movie_id
having count(*) = count(ug.genre_id);  -- do all match

编辑:

如果您只需要完全匹配,那么一种简单的方法是创建一个流派列表并在其上进行匹配:

select mg.movie_id
from (select mg.movie_id, group_concat(mg.genre_id order by mg.genre_id) as genres
      from movie_genres mg
      group by mg.movie_id
     ) mg join
     (select group_concat(ug.genre_id order by ug.genre_id) as genres
      from user_genres ug
      where ug.user_id = ?
     ) ug
     on mg.genres = ug.genres;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM