SQL Query,如何返回不在其他2个表中的元素

时间:2013-03-02 09:38:44

标签: sql join

这是我的数据

电影表:

id title
10 Promise Land
13 Alive
14 Bruce Almighty
15 Decay
19 Malcom X

用户表:

id username
1  Franck
2  Matt

存档表:

userid movieid
1      13
2      14
1      14

我想获取所有不在用户id = 1的存档表中的movies.id,movies.title。 我想使用JOINS(我不想选择选择)

结果应为:

id title
10 Promise Land
15 Decay
19 Malcom X

以下SQL失败:

SELECT a.id,a.title 
FROM db.movies AS a
LEFT JOIN db.archive AS b ON a.id = b.movieid
LEFT JOIN db.users AS c ON c.id = b.userid
WHERE b.movieid IS NULL OR b.userid !=1;

由于

4 个答案:

答案 0 :(得分:2)

使用JOINS。您将用户标识过滤器放入JOIN

SELECT
    a.id,a.title 
FROM
    binews.movies AS a
    LEFT JOIN
    binews.archive AS b ON a.id = b.movieid AND b.userid <> 1
WHERE
    b.movieid IS NULL;

但是,您实际上是在问“将我的电影放在归档表中此用户不存在的地方”

SELECT
    a.id,a.title 
FROM
    binews.movies AS a
WHERE
    NOT EXISTS (SELECT *
          FROM
             binews.archive AS b
          WHERE
             a.id = b.movieid AND b.userid <> 1);

这一般更为正确。在某些情况下,您将从LEFT JOIN获取多行,其中userid多次使用相同的行。要纠正这个问题,你需要添加处理的DISTINCT。

但是,EXISTS删除了这个多行输出。

有关详情,请参阅此处:http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/

答案 1 :(得分:1)

在SQLServer2005 +中,您可以使用带有EXISTS和EXCEPT运算符的选项

SELECT *
FROM dbo.movies
WHERE EXISTS (
              SELECT id
              EXCEPT
              SELECT movieid
              FROM archive
              WHERE userid = 1
              ) 

SQLFiddle上的演示

带有NOT EXISTS和INTERSECT运算符的

OR 选项

SELECT *
FROM dbo.movies
WHERE NOT EXISTS (                            
                  SELECT movieid
                  FROM archive
                  WHERE userid = 1
                  INTERSECT 
                  SELECT id
                  ) 

SQLFiddle上的演示

答案 2 :(得分:0)

select * from binews.movies 
      where id not in(select movieid from binews.archive where userid<>1 )

答案 3 :(得分:0)

感谢gbn。这是一个带有修正“AND b.userid = 1”

的解决方案
SELECT
    a.id,a.title 
FROM
    binews.movies AS a
    LEFT JOIN
    binews.archive AS b ON a.id = b.movieid AND b.userid=1
WHERE
b.movieid IS NULL