我读到子查询的输出并不重要,只有它的存在才重要。但是,当我更改子查询中的代码时,为什么我的输出发生了变化?这些是表格:
mysql> select * from boats;
+------+-----------+-------+
| bid | bname | color |
+------+-----------+-------+
| 101 | Interlake | blue |
| 102 | Interlake | red |
| 103 | Clipper | green |
| 104 | Marine | red |
+------+-----------+-------+
mysql> select * from sailors;
+------+---------+--------+------+
| sid | sname | rating | age |
+------+---------+--------+------+
| 22 | Dustin | 7 | 45 |
| 29 | Brutus | 1 | 33 |
| 31 | Lubber | 8 | 55.5 |
| 32 | Andy | 8 | 25.5 |
| 58 | Rusty | 10 | 35 |
| 64 | Horatio | 7 | 35 |
| 71 | Zorba | 10 | 16 |
| 74 | Horatio | 9 | 40 |
| 85 | Art | 3 | 25.5 |
| 95 | Bob | 3 | 63.5 |
+------+---------+--------+------+
10 rows in set (0.00 sec)
mysql> select * from reserves;
+------+------+------------+
| sid | bid | day |
+------+------+------------+
| 22 | 101 | 1998-10-10 |
| 22 | 102 | 1998-10-10 |
| 22 | 103 | 1998-10-08 |
| 22 | 104 | 1998-10-08 |
| 31 | 102 | 1998-11-10 |
| 31 | 103 | 1998-11-06 |
| 31 | 104 | 1998-11-12 |
| 64 | 101 | 1998-09-05 |
| 64 | 102 | 1998-09-08 |
| 74 | 103 | 1998-09-08 |
+------+------+------------+
select sname from sailors s where exists(select * from reserves r where r.bid=103);
+---------+
| sname |
+---------+
| Dustin |
| Brutus |
| Lubber |
| Andy |
| Rusty |
| Horatio |
| Zorba |
| Horatio |
| Art |
| Bob |
+---------+
10 rows in set (0.00 sec)
mysql> select sname from sailors s where exists(select * from reserves r where r.bid=103 and r.sid=s.sid);
+---------+
| sname |
+---------+
| Dustin |
| Lubber |
| Horatio |
+---------+
另外,我不能理解什么r.s sid=s。希德在这里干什么。所有的储备已经从水手表。请有人给我解释一下。
EXISTS
是一个布尔运算符,它指示您传递给它的子查询中是否有任何行。当你执行以下命令时:
EXISTS(SELECT * FROM reserves r WHERE r.bid=103)
在Reserves表中找到条件为bid = 103
的第一行后返回TRUE。查询的第一部分并不重要,不管你的SELECT
存在和MySQL引擎会忽略它,只是WHERE
子句是使差异的部分,你可以使用存在,甚至像这样:
EXISTS(SELECT 1 FROM reserves r WHERE r.bid=103)
在上面的查询中,没有任何依赖于main查询中的值,没有任何依赖于Sailors表,如果在Reserves表中有任何一行bid = 103
,那么它总是返回TRUE。
在第二个带有EXISTS的子查询中,有一个不同的WHERE子句,它依赖于主查询字段的值,所以每行会有不同的结果:
EXISTS(SELECT * FROM reserves r WHERE r.bid=103 AND r.sid=s.sid)
在上面的查询中,对于水手表中的每一行,MySQL使用sid
值在EXISTS操作符中产生子查询的WHERE
条件,因此如果储备金表中有任何行有bid = 103
和sid = Sailors.sid
,那么它将为水手表中的一行返回TRUE
,并且对于那些在储备金表中没有这样的记录,它将返回False,最后您将得到不同的结果
对于sailors中的每个名字,独立地,子查询都存在。因此,我得到了所有的名字。在第二个查询中,我添加了s.s sid=r。Sid,它链接主查询和子查询。它检查是否有sname,如果bid=103,如果s.sid=r.sid。
如果我说对了,请评论一下。