1
ACTOR (id, fname, lname, gender)
MOVIE (id, name, year, rank)
CASTS (pid, mid, role)
WHERE pid references ACTOR id
mid references Movie id

列出 x 没有 y 的电影(x 和 y 是演员)。

我发现很难用 NOT in 构造 SQL。这是我的尝试。由于第二个演员不在场,我无法完成

SELECT m.name
FROM MOVIE m
WHERE m.id NOT IN (SELECT c.mid
                       FROM CASTS c, ACTOR a
                       WHERE c.pid = a.id AND a.name = "adam..") 
4

4 回答 4

4

使用NOT EXISTS

SELECT m.name                       -- Show the names                      
FROM movie m                        -- of all movies
WHERE EXISTS                        -- that there was
      ( SELECT *                    -- a role
        FROM casts c                -- casted to
          JOIN actor a              -- actor with
            ON c.pid = a.id
        WHERE c.mid = m.id  
          AND a.name = 'Actor X'    -- name X
      ) 
  AND NOT EXISTS                    -- and there was not
      ( SELECT *                    -- any role
        FROM casts c                -- casted
          JOIN actor a              -- to actor with
            ON c.pid = a.id
        WHERE c.mid = m.id 
          AND a.name = 'Actor Y'    -- name Y
      ) ;

您也可以使用NOT IN. 请注意,如果or列NULL中有行,这可能会给您带来意想不到的结果:movie.idcasts.mid

SELECT m.name                       -- Show the names                      
FROM movie m                        -- of all movies
WHERE m.id IN                       -- but keep only the movies that
      ( SELECT c.mid                -- movies that
        FROM casts c                -- had a role casted to
          JOIN actor a              -- actor with
            ON c.pid = a.id
        WHERE a.name = 'Actor X'    -- name X
      ) 
  AND m.id NOT IN                   -- and not the movies
      ( SELECT c.mid                -- that
        FROM casts c                -- had a role casted
          JOIN actor a              -- to actor with
            ON c.pid = a.id
        WHERE a.name = 'Actor Y'    -- name Y
      ) ;
于 2013-05-02T16:38:20.617 回答
2

您还可以使用经常被忽视的MINUS

SELECT Movie.id, Movie.name
  FROM Actor
  INNER JOIN Casts ON Actor.id = Casts.pid
  INNER JOIN Movie ON Casts.mid = Movie.id
  WHERE Actor.id = 1
MINUS SELECT Movie.id, Movie.name
  FROM Actor
  INNER JOIN Casts ON Actor.id = Casts.pid
  INNER JOIN Movie ON Casts.mid = Movie.id
  WHERE Actor.id = 2

上述WHERE Actor.id查询中的 可以替换为其他方式来唯一标识演员,例如通过他们的姓名。

于 2013-05-02T16:24:55.923 回答
1
SELECT  a.*
FROM    Movie a
        INNER JOIN Casts b
            ON a.ID = b.mID
        INNER JOIN Actor c
            ON b.pid = c.ID
        LEFT JOIN
        (
            SELECT  aa.mid
            FROM    Casts aa
                    INNER JOIN Actor bb
                        ON aa.pid = bb.ID
            WHERE   bb.fName = 'Y_Name'
        ) d ON  a.id = d.mid
WHERE   c.fname = 'X_Name' AND
        d.mid IS NULL

对子查询进行额外连接的原因是因为我们正在按参与者的名称过滤记录。


假设你有这些记录

演员

╔════╦════════╗
║ ID ║ FNAME  ║
╠════╬════════╣
║  1 ║ X_Name ║
║  2 ║ Y_Name ║
╚════╩════════╝

电影

╔════╦══════╗
║ ID ║ NAME ║
╠════╬══════╣
║  1 ║ Mov1 ║
║  2 ║ Mov2 ║
║  3 ║ Mov3 ║
╚════╩══════╝

投掷

╔═════╦═════╗
║ PID ║ MID ║
╠═════╬═════╣
║   1 ║   1 ║ <<== EXPECTED OUTPUT since Y_NAME is not present
║   1 ║   2 ║                      on Movie Mov1
║   2 ║   2 ║
║   1 ║   3 ║
║   2 ║   3 ║
╚═════╩═════╝

输出

╔════╦══════╗
║ ID ║ NAME ║
╠════╬══════╣
║  1 ║ Mov1 ║
╚════╩══════╝
于 2013-05-02T16:15:00.557 回答
1

首先获取演员 X 的所有电影。然后检查过滤掉所有还包含演员 Y 的电影。

SELECT m.name
FROM MOVIE m, CASTS c, ACTOR a
WHERE m.id = c.mid
    AND c.pid = a.id
    AND a.name = "ACTOR X"
    AND NOT EXISTS (
        SELECT 1
        FROM CASTS c1, ACTOR a1
        WHERE c1.pid = a1.id
            AND m.id = c1.mid
            AND a1.name = "ACTOR Y"
    )
于 2013-05-02T16:17:40.260 回答