使用从另一个表MYSQL获取的值从一个表中选择行

Sta*_*umo 16 mysql

我目前在我的数据库中有2个mysql表

FilmFilm_Ratings_Report

Film的主要关键filmid是用于识别Film_Ratings_Report表中的胶片评级.

我想知道是否可以使用MYSQL查询来搜索评级表并收集符合特定条件的所有电影ID,然后使用所选ID从电影表中获取电影标题.下面是使用哪个MYSQL查询不起作用:

SELECT * 
FROM film 
UNION SELECT filmid 
      FROM film_rating_report 
      WHERE rating = 'GE' 
      LIMIT 0,0
Run Code Online (Sandbox Code Playgroud)

我对MYSQL比较绿,对此有所帮助.

提前致谢

SG *_* 86 16

SELECT * FROM film WHERE id IN 
  (SELECT filmid FROM film_rating_report WHERE rating = 'GE');
Run Code Online (Sandbox Code Playgroud)

应该管用


ype*_*eᵀᴹ 14

看起来你想要一个半连接,例如一个只需要来自2个连接表之一的数据的连接.在这种情况下,film其中存在匹配行的所有行都film_rating_report具有所需的条件(rating = 'GE').

这并不完全等同于通常的连接,因为即使第二张表中有2行(或更多)(电影的2个等级,两者都有'GE'),我们仍然希望电影一次显示,而不是两次(或更多)因为它将以通常的连接显示.

有多种方式可以编写半连接,最常用的是:

  • 使用EXISTS相关子查询(@ Justin的答案):

    SELECT t1.* 
    FROM film t1 
    WHERE EXISTS (SELECT filmid 
                  FROM film_rating_report t2
                  WHERE t2.rating = 'GE'
                  AND t2.filmid = t1.id);
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用IN(不相关的)子查询(@SG 86的答案):(
    这应该非常谨慎地使用,因为它可能会返回意外的结果 - 或者根本没有 - 如果连接列(filmid在这种情况下是两个)可以为空)

    SELECT * 
    FROM film 
    WHERE id IN 
      ( SELECT filmid 
        FROM film_rating_report 
        WHERE rating = 'GE'
      );
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用通常JOIN的a GROUP BY来避免结果中的重复行(@Tomas'的回答):(
    并注意这个特定的使用GROUP BY只在MySQL和Postgres的最新版本中工作,如果你想在其他地方写一个类似的查询DBMS,你必须包括所有列:GROUP BY f.filmid, f.title, f.director, ...)

    SELECT f.*
    FROM film AS f
        JOIN film_rating_report AS frr
             ON f.filmid = frr.filmid
    WHERE frr.rating = 'GE' 
    GROUP BY f.filmid ;
    
    Run Code Online (Sandbox Code Playgroud)
  • @ Tomas'es的一个变体回答,在GROUP BY派生表上完成,然后是JOIN:

    SELECT f.*
    FROM film AS f
        JOIN 
            ( SELECT filmid
              FROM film_rating_report
              WHERE rating = 'GE'
              GROUP BY filmid
            ) AS frr
          ON f.filmid = frr.filmid ;
    
    Run Code Online (Sandbox Code Playgroud)

使用哪一个取决于RDBMS和您使用的特定版本(例如,IN在大多数MySQL版本中应避免使用子查询,因为它们可能会产生低效的执行计划),特定的表大小,分布,索引等.

我通常更喜欢这个EXISTS解决方案,但是首先使用您将来或期望拥有的表大小来测试各种查询并尝试为您的案例找到最佳查询索引组合,这绝不会让您感到痛苦.


另外:如果组合有一个独特的限制film_rating_report (filmid, rating),这意味着没有任何一部电影可以获得两个相同的评级,或者如果有一个更严格(但更合理)的独特限制,film_rating_report (filmid)这意味着每部电影最多只有一个评级,您可以简化JOIN解决方案(并摆脱所有其他查询):

    SELECT f.*
    FROM film AS f
        JOIN film_rating_report AS frr
             ON f.filmid = frr.filmid
    WHERE frr.rating = 'GE' ;
Run Code Online (Sandbox Code Playgroud)