MYSQL-选择表A中不在表B中的行,但表C中的行除外

MYSQL-选择表A中不在表B中的行,但表C中的行除外,mysql,sql,mysql-select-db,Mysql,Sql,Mysql Select Db,表A: dvdID…….dvdTitle d01…………复仇者 d02…………复仇者 d03…………蜘蛛侠 表B: 租赁ID…….dvdID r01……….d01 r02……….d02 r03……….d03 表C: returnID…….rentID t01…………r01 我想选择不在表B(租用)中的dvd,但在表C(归还)中除外 所以输出应该是这样的: 输出: dvdID…….dvdTitle d01…………复仇者 您能帮助我吗?您可以在SQL条件中使用存在量词,由EXISTS关键字表示: S

表A:

dvdID…….dvdTitle

d01…………复仇者

d02…………复仇者

d03…………蜘蛛侠

表B:

租赁ID…….dvdID

r01……….d01

r02……….d02

r03……….d03

表C:

returnID…….rentID

t01…………r01

我想选择不在表B(租用)中的dvd,但在表C(归还)中除外 所以输出应该是这样的:

输出:

dvdID…….dvdTitle

d01…………复仇者


您能帮助我吗?

您可以在SQL条件中使用存在量词,由
EXISTS
关键字表示:

SELECT *
FROM TableA a
WHERE NOT EXISTS (        -- No rental record
    SELECT *
    FROM TableB b
    WHERE b.dvdID=a.dvdID -- The record is for this DVD, and...
      AND NOT EXISTS (    -- ...there is no return record
          SELECT * FROM TableC c WHERE c.rentID=b.rentID
      )
)

该查询读起来几乎像一个结构糟糕的英语句子,但它解释了发生了什么。

您可以在SQL条件中使用存在量词,由
EXISTS
关键字表示:

SELECT *
FROM TableA a
WHERE NOT EXISTS (        -- No rental record
    SELECT *
    FROM TableB b
    WHERE b.dvdID=a.dvdID -- The record is for this DVD, and...
      AND NOT EXISTS (    -- ...there is no return record
          SELECT * FROM TableC c WHERE c.rentID=b.rentID
      )
)
这个查询读起来几乎像一个结构糟糕的英语句子,但它解释了发生了什么。

试试这个

SELECT *
FROM A 
WHERE (NOT EXISTS (SELECT * FROM B WHERE B.dvdID=A.dvdID))
   OR (EXISTS (SELECT * FROM C,B WHERE C.rentID=B.rentID and B.dvdID=A.dvdID))
这里是

试试这个

SELECT *
FROM A 
WHERE (NOT EXISTS (SELECT * FROM B WHERE B.dvdID=A.dvdID))
   OR (EXISTS (SELECT * FROM C,B WHERE C.rentID=B.rentID and B.dvdID=A.dvdID))

这是您的样本数据集中的

很明显,您需要租在表C中的dvd。为此,您可以执行一个简单的
内部
连接,表3中的最后一个连接将满足表1中dvd的租在条件

select t1.* FROM
Table1 t1
LEFT JOIN Table2 USING(dvdID)
JOIN Table3 USING(rentID)

从您的示例数据集可以清楚地看出,您需要租在表C中的dvd。为此,您可以通过一个简单的
内部
连接,表3中的最后一个连接将满足表1中dvd的租在条件

select t1.* FROM
Table1 t1
LEFT JOIN Table2 USING(dvdID)
JOIN Table3 USING(rentID)
试试这个:

SELECT TableA.dvdID, TableA.dvdTitle 
FROM TableA
LEFT JOIN TableB ON TableA.dvdID = TableB.dvdID
LEFT JOIN TableC ON TableC.rentID = TableB.rentID
WHERE TableB.rentID IS NULL
   OR (TableB.rentID IS NOT NULL
       AND TableC.returnID IS NOT NULL)
试试这个:

SELECT TableA.dvdID, TableA.dvdTitle 
FROM TableA
LEFT JOIN TableB ON TableA.dvdID = TableB.dvdID
LEFT JOIN TableC ON TableC.rentID = TableB.rentID
WHERE TableB.rentID IS NULL
   OR (TableB.rentID IS NOT NULL
       AND TableC.returnID IS NOT NULL)
试试这个 选择1

试试这个 选择1


您应该使用
连接
而不是
存在/不存在

SELECT 
    a.*
FROM TableA a
    LEFT join TableB b
        on b.id=a.id
    LEFT Join TableC c 
        on c.id=a.id
WHERE
    b.id is null 
    OR (b.id is not null AND c.id is not null)

您应该使用
连接
而不是
存在/不存在

SELECT 
    a.*
FROM TableA a
    LEFT join TableB b
        on b.id=a.id
    LEFT Join TableC c 
        on c.id=a.id
WHERE
    b.id is null 
    OR (b.id is not null AND c.id is not null)


如果您看到模式和示例数据集,那么tableA和tableC之间没有直接关系,因此这将不会产生reultsetIt。使用外部联接比使用外部联接更快EXISTS@StanislavL十年前可能是这样,但现在已经不太接近事实了。所有非toy RDBMS引擎很久以前就已经解决了这一问题,因此
EXIST
查询的速度几乎与具有联接的等效查询的速度一样快。不,您的子查询将针对TableA中的每一行执行,以与a.id进行比较。您可以尝试重新生成自己。重新生成案例(创建一个虚拟表,并用大量行填充它们,然后运行查询,再编写一个带有连接的查询)。它不依赖于RDBMS。如果您看到模式和示例数据集,那么tableA和tableC之间没有直接关系,因此这不会产生reultsetIt。使用外部联接比使用外部联接更快EXISTS@StanislavL十年前可能是这样,但现在已经不太接近事实了。所有非toy RDBMS引擎很久以前就已经解决了这一问题,因此
EXIST
查询的速度几乎与具有联接的等效查询的速度一样快。不,您的子查询将针对TableA中的每一行执行,以与a.id进行比较。您可以尝试重新生成自己。重新生成案例(创建一个虚拟表,并用大量行填充它们,然后运行查询,再编写一个带有连接的查询)。它不依赖于RDBMS。选择不在表B+1中用左连接替换的dvd时,它应该是外部连接,表2.id为null,但也应该是表2.id为null的位置。选择不在表B+1中用左连接替换的dvd时,它应该是外部连接,表2.id为null,但也应该是表2.id为null的位置,你说得对,先生。也许是因为你使用SQLFiddle真的帮了大忙,谢谢:)很高兴它帮了你:)不管怎样,你能给我一些建议(可能是电子书之类的参考资料)来帮助我学习mySQL吗?嗯,我很久以前(大约5年前)就从教学大纲书中学习过SQL。你只需要寻找SQL教程,通过实践你就会掌握它。没有任何教程可以与“实践”相比,只有实践才能让你更加自信。只需尝试一些示例,并使用
连接、分组依据、排序依据、聚合函数来完成这些都是SQL的基础知识,在每个DBMS中都很常用。很好,先生,你说得对。也许是因为你使用SQLFiddle真的帮了大忙,谢谢:)很高兴它帮了你:)不管怎样,你能给我一些建议(可能是电子书之类的参考资料)来帮助我学习mySQL吗?嗯,我很久以前(大约5年前)就从教学大纲书中学习过SQL。你只需要寻找SQL教程,通过实践你就会掌握它。没有任何教程可以与“实践”相比,只有实践才能让你更加自信。只需尝试一些示例,并使用
连接、分组方式、排序方式、聚合函数来完成这些操作
这些都是SQL的基础,在每个DBMS中都很常用。