cs50 pset7电影sql.12

时间:2020-05-01 03:12:13

标签: sql sqlite

有人可以帮助我解决我的SQL问题吗? 我要处理五张桌子。
预期的结果是

  1. ”编写SQL查询以列出所有电影的标题,其中 约翰尼·德普(Johnny Depp)和海伦娜·博纳姆·卡特(Helena Bonham Carter)出演了“”
  2. 您的查询应该输出一个表格,其中每列电影的标题都为一列。
  3. 您可以假设数据库中只有一个人 约翰尼·德普(Johnny Depp)的名字。
  4. 您可以假设数据库中只有一个人,名字叫Helena Bonham Carter。

     CREATE TABLE movies (
                         id INTEGER,
                         title TEXT NOT NULL,
                         year NUMERIC,
                         PRIMARY KEY(id)
                        ); 
    
     CREATE TABLE stars (
                     movie_id INTEGER NOT NULL,
                     person_id INTEGER NOT NULL,
                     FOREIGN KEY(movie_id) REFERENCES movies(id),
                     FOREIGN KEY(person_id) REFERENCES people(id)
                       ); 
    
    CREATE TABLE directors (
                     movie_id INTEGER NOT NULL,
                     person_id INTEGER NOT NULL,
                     FOREIGN KEY(movie_id) REFERENCES movies(id),
                     FOREIGN KEY(person_id) REFERENCES people(id)
                 ); 
    
    CREATE TABLE ratings (
                     movie_id INTEGER NOT NULL,
                     rating REAL NOT NULL,
                     votes INTEGER NOT NULL,
                     FOREIGN KEY(movie_id) REFERENCES movies(id)
                   ); 
    
    CREATE TABLE people (
                     id INTEGER,
                     name TEXT NOT NULL,
                     birth NUMERIC,
                     PRIMARY KEY(id)
                 );
    

这将导致59行,而应该只有6行。

 SELECT title FROM movies  WHERE id IN (SELECT DISTINCT movie_id FROM
 stars WHERE person_id =  (SELECT id FROM people  WHERE name IN
 ("Johnny Depp", "Helena Bonham Carter")));

我看到其他有关使用“ WHERE IN”的帖子会有所帮助,而我确实在使用它。

6 个答案:

答案 0 :(得分:2)

我首先使用了一些 join 语句来得到一个表格,其中包含这两位演员出演的所有电影片名。

我通过按电影标题分组来清理数据,将相似的电影标题分组。

然后我使用 COUNT 函数查看电影名称被提及两次的地方,这意味着两个演员都参与了。

-- inspired by https://stackoverflow.com/a/477035

SELECT movies.title FROM stars
JOIN movies ON stars.movie_id = movies.id
JOIN people ON stars.person_id = people.id
WHERE people.name IN ('Johnny Depp', 'Helena Bonham Carter')
GROUP BY movies.title
HAVING COUNT(movies.title) = 2;

答案 1 :(得分:1)

使用JOININTERSECT帮助我解决了这一问题。

类似这样的东西:

Select title from movies 
join stars on stars.movie_id = movies.id 
join people on people.id = stars.person_id 
where people.name = "Helena Bonham Carter" 
INTERSECT 
Select title from movies 
join stars on stars.movie_id = movies.id 
join people on people.id = stars.person_id 
where people.name = "Johnny Depp";

答案 2 :(得分:1)

我的用法如下,它比使用INTERSECT快一点。

select title from movies where id in (
select movie_id from stars
join people
on stars.person_id = people.id
where name = "Helena Bonham Carter" and movie_id in
(select movie_id from stars where person_id in 
(select id from people where name = "Johnny Depp")
))
order by title

答案 3 :(得分:1)

使用计数:

SELECT title FROM movies WHERE id IN 
(SELECT movie_id FROM 
(SELECT count(person_id) as together, movie_id FROM stars WHERE person_id IN
(SELECT id FROM people WHERE name IN ('Johnny Depp','Helena Bonham Carter')) 
GROUP BY movie_id) 
WHERE together > 1);

答案 4 :(得分:0)

我在这里测试了所有推荐,我相信这是迄今为止最快的一个,虽然它看起来有点神秘:

时间:0.48

SELECT title FROM movies WHERE id IN 
(
    SELECT movie_id FROM stars WHERE person_id =
        (SELECT id FROM people WHERE name = "Helena Bonham Carter") 
    and
        movie_id IN
            (
                 SELECT movie_id FROM stars WHERE person_id =
                     (SELECT id FROM people WHERE name = "Johnny Depp")
            )
)

答案 5 :(得分:0)

在这种情况下,我没有使用 JOIN 选项,而是更多地作为传统风格,以便在我的脑海中得到更好的效果。我还是会尝试另一种方式。但是这个选项效果很好。

SELECT movies.title FROM movies
WHERE id IN (SELECT movie_id FROM stars WHERE person_id IN
(SELECT id FROM people WHERE name = "Johnny Depp"))
AND id IN (SELECT movie_id FROM stars WHERE person_id IN
(SELECT id FROM people WHERE name = "Helena Bonham Carter"));