Mysql 正在搜索不在关系中的多行n:m
类似问题 与上面的问题非常相似,但有一点不同,我需要找到一个用户列表,这些用户在电影列表中至少没有看过一部电影 假设有两个表“movies”和“users”,它们之间有一个n:m关系,一个表“seed”描述了这种关系 我需要找出任何数量的给定用户,以及任何数量的给定电影所有用户,从给定列表中,至少没有看过一部给定电影 这是否可以在单个查询中实现?我想不出一个办法Mysql 正在搜索不在关系中的多行n:m,mysql,sql,Mysql,Sql,类似问题 与上面的问题非常相似,但有一点不同,我需要找到一个用户列表,这些用户在电影列表中至少没有看过一部电影 假设有两个表“movies”和“users”,它们之间有一个n:m关系,一个表“seed”描述了这种关系 我需要找出任何数量的给定用户,以及任何数量的给定电影所有用户,从给定列表中,至少没有看过一部给定电影 这是否可以在单个查询中实现?我想不出一个办法 编辑:这里有一个试图解决这个问题的演示,问题是它返回的用户没有看到给定列表中的所有电影。我们需要的是一个没有看过该列表中任何电影的用户
编辑:这里有一个试图解决这个问题的演示,问题是它返回的用户没有看到给定列表中的所有电影。我们需要的是一个没有看过该列表中任何电影的用户:考虑到用户和电影表之间的n:m关系,并看到中间表
SELECT * FROM Users u WHERE NOT EXISTS (SELECT UserId FROM Seen s WHERE s.UserId = u.ID)
考虑到用户和Movies表之间的n:m关系,此查询将返回在SEED表中没有任何相关记录的用户,中间表为SEED
SELECT * FROM Users u WHERE NOT EXISTS (SELECT UserId FROM Seen s WHERE s.UserId = u.ID)
此查询将返回在SEED表中没有任何相关记录的用户我想说的是,将用户表连接到SEED表(并将该表连接到movies表) (根据MatBailie的评论编辑代码) 在JOIN子句中添加列表限制(而不是MatBailie向我指出的WHERE子句),您会得到类似的结果(下面的代码应该适用于SQL Server,但类似的代码也适用于MySql):
我会说类似于将users表连接到seed表(并将该表连接到movies表)的左键 (根据MatBailie的评论编辑代码) 在JOIN子句中添加列表限制(而不是MatBailie向我指出的WHERE子句),您会得到类似的结果(下面的代码应该适用于SQL Server,但类似的代码也适用于MySql):
此查询将为您提供所需的结果。我假设你的基本结构是:
users (id int, name varchar(20));
movies (id int, title varchar(20));
seen (user_id int, movie_id int);
SELECT u.*
FROM users u
LEFT JOIN seen s
ON s.user_id = u.id AND s.movie_id IN (movielist)
WHERE s.user_id IS NULL AND u.id IN (userlist)
其中s.user\u id为空
条件意味着左连接
将为您提供在movielist
中未看过任何电影的所有用户,并且(userlist)中的u.id将结果仅限于该组用户。
您可以修改
子句中的,以匹配您感兴趣的电影和用户列表。我已经做了一个小计划
更新
我误解了这个问题;所需结果适用于未看过列表中一部(或多部)电影的用户。此查询解决了该问题:
SELECT u.*
FROM musers u
LEFT JOIN seen s
ON s.user_id = u.id AND s.movie_id IN (1, 2)
WHERE u.id IN (1, 2, 3)
GROUP BY u.id
HAVING COUNT(s.movie_id) < 2
选择u*
来自缪斯大学
左联
在(1,2)中的s.user_id=u.id和s.movie_id上
其中u.id位于(1,2,3)
按u.id分组
计数(s.movie_id)<2
JOIN
和WHERE
的结果是用户(1、2、3)和他们看过的电影。如果他们已经看过电影列表中的所有电影(1,2)
,则中的电影计数将为2,否则,如果他们没有看过一部(或多部)电影,则计数将小于2。这是一个例子。请注意,当电影列表的长度更改时,HAVING
子句中的2
必须更改以匹配电影列表的长度。此查询应提供所需的结果。我假设你的基本结构是:
users (id int, name varchar(20));
movies (id int, title varchar(20));
seen (user_id int, movie_id int);
SELECT u.*
FROM users u
LEFT JOIN seen s
ON s.user_id = u.id AND s.movie_id IN (movielist)
WHERE s.user_id IS NULL AND u.id IN (userlist)
其中s.user\u id为空
条件意味着左连接
将为您提供在movielist
中未看过任何电影的所有用户,并且(userlist)
中的u.id将结果仅限于该组用户。
您可以修改
子句中的,以匹配您感兴趣的电影和用户列表。我已经做了一个小计划
更新
我误解了这个问题;所需结果适用于未看过列表中一部(或多部)电影的用户。此查询解决了该问题:
SELECT u.*
FROM musers u
LEFT JOIN seen s
ON s.user_id = u.id AND s.movie_id IN (1, 2)
WHERE u.id IN (1, 2, 3)
GROUP BY u.id
HAVING COUNT(s.movie_id) < 2
选择u*
来自缪斯大学
左联
在(1,2)中的s.user_id=u.id和s.movie_id上
其中u.id位于(1,2,3)
按u.id分组
计数(s.movie_id)<2
JOIN
和WHERE
的结果是用户(1、2、3)和他们看过的电影。如果他们已经看过电影列表中的所有电影(1,2)
,则中的电影计数将为2,否则,如果他们没有看过一部(或多部)电影,则计数将小于2。这是一个例子。请注意,当电影列表的长度更改时,HAVING
子句中的2
必须更改以匹配电影列表的长度。请提供示例数据和所需结果。您尝试查询也很有帮助。此信息不依赖于其他问题。请提供示例数据和期望结果。您尝试查询也很有帮助。不要依赖于另一个问题来获取这些信息。这个问题涉及“任何数量的给定电影”,而不是“任何电影”。我认为您的代码没有考虑到这一点。问题涉及“任意数量的给定电影”,而不是“任何电影”。我认为您的代码没有考虑到这一点。用户。列表中的某些内容和电影。列表中的某些内容需要移出位置,进入左连接,否则您会将它们变回内部连接。尽管公平地说,有两种方法可以解决这个问题。但我承认,在join子句中添加条件感觉更自然。我感到困惑,这似乎应该有效,但事实并非如此。我在下一个回复中将此解决方案放入@Nick提供的rexter中(非常感谢,我不知道此工具)。结果令人困惑。我经验