包含列表中所有项的SQL查询记录

时间:2014-05-10 06:27:48

标签: mysql sql oracle sqlite relational-division

我有以下表格:

MOVIES

  MOVIE_ID TITLE
---------- -----------------------------
         1 The Shawshank Redemption
         2 The Godfather
         3 The Godfather: Part II
         4 The Dark Knight
         5 Pulp Fiction
         6 The Good, the Bad and the Ugly
         7 Schindler's List
         8 Angry Men
         9 Fight Club
        10 Inception
        11 Forrest Gump

董事

DIRECTOR_ID NAME
----------- -------------------------
          1 Tim Robbins
          2 Morgan Freeman
          3 Marlon Brando
          4 Al Pachino
          5 Robert De Niro
          6 Christian Bale
          7 Heath Ledger
          8 John Travola
          9 Uma Thurman
         10 Clint Eastwood
         11 Eli Wallach

直接

  MOVIE_ID DIRECTOR_ID
---------- -----------
         1           1
         1           2
         2           3
         2           4
         3           4
         3           5
         4           6
         4           7
         5           8
         5           9
         6          10

我想要一个返回所有导演x,y和z作为导演的电影的查询:

示例:

  

如果我用 Al Pachino Clint Eastwood 寻找电影,   应该返回没有,因为我没有一部同时拥有的电影   他们是导演。

     

但是如果我要用 Tim Robbins Morgan寻找一部电影   弗里曼,它应该返回 The Shawshank Redemption

如果使用上述设计无法完成,请建议替代方案。

我已尝试过但我的查询会返回结果:(

SELECT m.title FROM Movie m 
WHERE m.movie_id IN (
      SELECT d.movie_id FROM Direct d
      WHERE d.director_id IN (
           SELECT director_id FROM Director dir 
           WHERE name IN('Clint Eastwood', 'Al Pachino')));

4 个答案:

答案 0 :(得分:4)

这是达到此目的的一种方法,即分组,过滤,然后计算导演:

SELECT m.title 
FROM Movie m
     INNER JOIN Direct md
     on md.movie_id = m.movie_id
     INNER JOIN Directors d
     on md.director_id = d.director_id
WHERE 
     d.name IN('Clint Eastwood', 'Al Pachino')
GROUP BY m.title
HAVING COUNT(DISTINCT d.director_id) = 2;

SqlFiddle here

{出于兴趣,这些不是电影中的演员吗?}

答案 1 :(得分:1)

使用IN运算符,您的查询将返回包含任何这些导演的电影。

您必须分别检查每个导演:

SELECT *
FROM Movie
WHERE movie_id IN (SELECT movie_id
                   FROM Direct
                   WHERE director_id = (SELECT director_id
                                        FROM Directors
                                        WHERE name = 'Clint Eastwood'))
  AND movie_id IN (SELECT movie_id
                   FROM Direct
                   WHERE director_id = (SELECT director_id
                                        FROM Directors
                                        WHERE name = 'Al Pachino'))

或者,使用compound query构建两个导演的电影ID列表:

SELECT *
FROM Movie
WHERE movie_id IN (SELECT movie_id
                   FROM Direct
                   WHERE director_id = (SELECT director_id
                                        FROM Directors
                                        WHERE name = 'Clint Eastwood')
                   INTERSECT
                   SELECT movie_id
                   FROM Direct
                   WHERE director_id = (SELECT director_id
                                        FROM Directors
                                        WHERE name = 'Al Pachino'))

或者,从Direct表中获取这两位导演的所有记录,然后按电影分组,以便能够计算每部电影的导演数;我们需要剩下两个:

SELECT *
FROM Movie
WHERE movie_id IN (SELECT movie_id
                   FROM Direct
                   WHERE director_id IN (SELECT director_id
                                         FROM Directors
                                         WHERE name IN ('Clint Eastwood',
                                                        'Al Pachino')
                   GROUP BY movie_id
                   HAVING COUNT(*) = 2)

答案 2 :(得分:0)

最短的

   ;with cte as (      
    select m.title, ROW_NUMBER() over (partition by m.title order by dir.name) rn 
    from Movie m
    inner join Direct d on m.movie_id = d.movie_id
    inner join Director dir on dir.DIRECTOR_ID = d.director_id
    where dir.name IN ('Clint Eastwood', 'Al Pachino')
    )
    select * from cte where rn > 1

答案 3 :(得分:0)

您也可以尝试使用SQLite:

SELECT title
 FROM movie NATURAL JOIN direct NATURAL JOIN directors
 GROUP BY title
  HAVING GROUP_CONCAT(name)  LIKE '%Morgan Freeman%' AND GROUP_CONCAT(name)  LIKE '%Tim  Robbins%'
;

测试here