CS50 Pset 7 13.sql,我解不出来,嵌套sqlite3数据库

pgx2nnw8  于 2022-12-13  发布在  SQLite
关注(0)|答案(6)|浏览(164)

数据库电影.db
表格

导演(影片标识,人物标识)
电影(id,标题,年份)
人员(ID、姓名、出生)
分级(电影ID,分级,投票)
明星(影片标识,人物标识)
您可以下载**database**。

问题

我是编程新手,所以我决定从CS50哈佛课程开始,这里是问题和测试solution
在13.sql中,编写一个SQL查询,列出凯文·培根(Kevin Bacon)也主演的电影中的所有主演人员的姓名。查询应输出一个表,其中每个人的姓名都有一列。数据库中可能有多个名为凯文·培根(Kevin Bacon)的人。请确保只选择出生于1958年的凯文·培根(Kevin Bacon)。凯文·培根本人不应包括在结果列表中。

解决方案提示

执行13.sql将生成一个包含1列和176行的表。
在PowerShell或bash cat 13.sql | sqlite3 movies.db中执行代码
我的代码:

SELECT COUNT(name)
FROM people 
JOIN stars ON stars.person_id = people.id 
JOIN movies ON movies.id = stars.movie_id 
WHERE people.id IN(
SELECT stars.person_id 
FROM stars 
GROUP BY stars.person_id 
HAVING name = "Kevin Bacon");

问题:

当我执行代码时它停止工作,我不能和Kevin一起选星星

8aqjt8rx

8aqjt8rx1#

我发现以下步骤很有帮助:
1.获取Kevin Bacon的ID,条件是Kevin Bacon出生于1958年
1.使用Kevin Bacon的ID获取他的电影ID(提示:将table1中的ID与table2链接)
1.获取具有相同电影ID的其他明星的ID
1.得到这些明星的名字,并排除凯文培根(因为规范说他不应该包括在结果列表中)
注意:在代码的第一行中,可以使用SELECT name而不是COUNT(name)来获取人员的姓名

plicqrtu

plicqrtu2#

我试着在Zara的步骤回答:

SELECT people.name
FROM people
WHERE people.id = (
    SELECT stars.person_id
    FROM stars
    JOIN movies ON stars.movie_id = movies.id
    WHERE movies.id = (
        SELECT movies.id
        FROM movies
        JOIN stars ON stars.movie_id = movies.id
        JOIN people ON stars.person_id = people.id
        WHERE people.id = (
            SELECT id
            FROM people
            WHERE birth = 1958 AND name = "Kevin Bacon")
                    )
)

结果:

我一定是做错了步骤才得到这个结果
预期176行,但只有一行“Steve gutenberg ”

xienkqul

xienkqul3#

我没有使用任何Join,只是嵌套了条件。

SELECT people.name FROM people
WHERE people.id IN 
(
    SELECT stars.person_id FROM stars
    WHERE stars.movie_id IN 
    (
        SELECT stars.movie_id FROM stars
        WHERE stars.person_id IN
        (
            SELECT people.id FROM people
            WHERE people.name = "Kevin Bacon" AND 
            people.birth = 1958
        )
    )
)
AND people.name != "Kevin Bacon" 
GROUP BY people.name
8e2ybdfx

8e2ybdfx4#

我还在不使用JOIN而仅使用嵌套查询的情况下解决了这个问题:

SELECT name FROM people
WHERE id IN (
    SELECT person_id FROM stars
    WHERE movie_id IN (
        SELECT movie_id FROM stars
        WHERE person_id = (
            SELECT id FROM people
            WHERE name = "Kevin Bacon" AND birth = 1958)))
EXCEPT 
    SELECT name FROM people
    WHERE name = "Kevin Bacon" and birth = 1958;

我试图避免使用嵌套查询,但实际上,如果不使用嵌套查询,我就无法进入正确的路径。
我的代码如下:
1.获取出生于1958年的Kevin Bacon的ID。(返回Kevin Bacon的ID)
1.获取凯文·培根主演的所有电影。(返回凯文·培根主演的电影列表)
1.获取与每部电影相关的所有person_id(返回每部电影的person_id列表,包括Kevin Bacon的id)
1.除了凯文·培根本人。

ldioqlga

ldioqlga5#

在自上而下的层次结构中获取值,但要确保在正确的域中搜索它。获取所需的第一项内容是名称,但要在依赖于person_id的正确域中搜索它,然后再搜索movie_id。最后,要调用条件,我们必须重新调用people.id,因为条件依赖于people表中的数据。在每一步执行所需的JOIN是必不可少的。
若要从结果中移除Kevin Bacon,您可以使用EXCEPT保留字,并在其他查询中特别选择他。

SELECT name FROM people WHERE people.id
IN
( SELECT person_id FROM stars JOIN movies ON movies.id = stars.movie_id 
WHERE movie_id IN
( SELECT movie_id FROM movies JOIN stars ON stars.movie_id = movies.id JOIN people ON 
 people.id = stars.person_id WHERE people.id IN (
SELECT id FROM people WHERE people.name = "Kevin Bacon" AND people.birth = 1958 )))
EXCEPT
SELECT name FROM people WHERE people.name = "Kevin Bacon" AND people.birth = 1958
lzfw57am

lzfw57am6#

我通过在SQL中使用DISTINCTNOT EQUAL运算符解决了这个问题。
以下是我采取的步骤:

SELECT DISTINCT(name)
FROM people
JOIN stars ON stars.person_id = people.id
JOIN movies ON movies.id = stars.movie_id
WHERE movies.id IN
    (SELECT movie_id
     FROM movies
     JOIN stars ON stars.movie_id = movies.id
     JOIN people ON people.id = stars.person_id
     WHERE people.name = "Kevin Bacon"
       AND people.birth = 1958)
  AND people.name != "Kevin Bacon";

结果是176行不同的名称。

相关问题