MYSQL-选择表A中不在表B中的行,但表C中的行除外
表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…………复仇者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
您能帮助我吗?您可以在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中都很常用。