当前位置: 首页 > 面试题库 >

MySQL:查找不参与关系的行

鲁斯伯
2023-03-14
问题内容

我有两个表:“电影”和“用户”。两者之间存在n:m关系,描述用户观看过哪些电影。这用表格“
seen”描述。现在,我想为给定的用户找出他尚未看过的所有电影。我当前的解决方案是这样的:

SELECT *
FROM movies 
WHERE movies.id NOT IN (
     SELECT seen.movie_id 
     FROM seen 
     WHERE seen.user_id=123
)

这可以正常工作,但扩展性似乎不太好。有更好的方法吗?


问题答案:

这是不使用您显示的子查询方法来执行此查询的典型方法。这可以满足@Godeke的要求,以查看基于联接的解决方案。

SELECT * 
FROM movies m
 LEFT OUTER JOIN seen s
 ON (m.id = s.movie_id AND s.user_id = 123)
WHERE s.movie_id IS NULL;

但是,在大多数品牌的数据库中,此解决方案的性能可能比子查询解决方案差。最好使用EXPLAIN来分析两个查询,以查看在您的模式和数据下哪个查询会更好。

这是子查询解决方案的另一个变体:

SELECT * 
FROM movies m
WHERE NOT EXISTS (SELECT * FROM seen s 
                  WHERE s.movie_id = m.id 
                    AND s.user_id=123);

这是一个相关的子查询,必须为外部查询的每一行进行评估。通常这很昂贵,并且您的原始示例查询更好。另一方面,在MySQL中,“ NOT EXISTS”通常比“ column NOT IN (...)” 更好

同样,您必须测试每个解决方案并比较结果以确保确定。 在不衡量性能的情况下选择任何解决方案都是浪费时间。



 类似资料:
  • 问题内容: 我试图选择最多10条相关文章,其中相关文章是与其他文章具有3个或更多相同关键字的文章。 我的表结构如下: 我可以在一个查询中选择所有相关的文章ID和标题吗? 任何帮助是极大的赞赏。 问题答案: 假设标题也是唯一的 在何处排除“种子”文章 因为我并不在乎我匹配哪个标签,而只是在3个标签上匹配,所以我只需要tag_id并完全避免连接到标签表。因此,现在我将多对多表与其自身相连,以查找具有重

  • 使用指南 - 统计设置 - 第三方推广管理 - hm参数与utm参数的对应关系 百度统计通过落地页中URL的参数来识别该URL的广告信息,点此了解什么是URL参数。 百度统计标识广告信息一直采用hm参数,即hmsr、hmpl、hmcu、hmkw、hmci五个参数。同时也有用户习惯使用utm参数,即utm_source、utm_medium、utm_campaign、utm_term、utm_con

  • 我正在使用Hibernate 4.2.6、JSF2(Mojarra 2.1.13)和Tomcat 7.0.34来开发我的Web应用程序。我试图使用Hibernate注释定义两个类之间的OneToOne关系。我认为我做错了什么,因为我得到了一个ORA-02291异常:完整性约束(PER_VPT_F01)被违反-父密钥未找到。我花了将近8个小时试图找到错误在哪里,但没有任何成功。拜托,有人能看看这个代

  • 问题内容: 我试图弄清楚如何构建该数据库。之前我已经使用过Apple的核心数据,现在我正在从事另一个需要MySQL的项目。我是MySQL的新手,所以请放轻松。:) 在这个例子中,假设我有三个表,,,和。把它画出来,一个可以有多个s,但是一个只能有一个;每个都有其主键,我需要使用它来获取正确的信息。 那么如何在这里建立这样的关系呢?我听说过创建索引和外键,但不确定它们如何正常工作。 最后,我需要做的

  • 问题内容: 我有一个类似(简化)的表结构: 内容 content_has_content topic_has_content 任何主题都可以具有多个“内容”,任何“内容”都可以具有多个“子内容”(内容实例)。对于给定的id_topic,我想从链接的内容,子内容,子内容的子内容等中接收所有my_string1的列表。 我了解“ WITH”不适用于mysql,但找不到很好的递归替代方法。 谢谢丹尼尔

  • 这个查询工作正常,但速度很慢。 此数据库有3个字段: 我需要这个: MP3、artist和artist_relations每个都有超过20000张唱片 -- 如果不存在则创建表(int(11)NOT NULL,int(11)NOT NULL)engine=innoDB默认charset=latin1; -- 如果不存在则创建表(int(11)不为NULL AUTO_INCREMENT,varcha