考虑下表:
mysql> select * from phone_numbers;
+-------------+------+-----------+
| number | type | person_id |
+-------------+------+-----------+
| 17182225465 | home | 1 |
| 19172225465 | cell | 1 |
| 12129876543 | home | 2 |
| 13049876543 | cell | 2 |
| 15064223454 | home | 3 |
| 15064223454 | cell | 3 |
| 18724356798 | home | 4 |
| 19174335465 | cell | 5 |
+-------------+------+-----------+
我正试图找到那些有家庭电话但没有手机的人。
此查询有效:
mysql> select h.*
-> from phone_numbers h
-> left join phone_numbers c
-> on h.person_id = c.person_id
-> and c.type = 'cell'
-> where h.type = 'home'
-> and c.number is null;
+-------------+------+-----------+
| number | type | person_id |
+-------------+------+-----------+
| 18724356798 | home | 4 |
+-------------+------+-----------+
但这个不是:
mysql> select h.*
-> from phone_numbers h
-> left join phone_numbers c
-> on h.person_id = c.person_id
-> and h.type = 'home'
-> and c.type = 'cell'
-> where c.number is null;
+-------------+------+-----------+
| number | type | person_id |
+-------------+------+-----------+
| 19172225465 | cell | 1 |
| 13049876543 | cell | 2 |
| 15064223454 | cell | 3 |
| 18724356798 | home | 4 |
| 19174335465 | cell | 5 |
+-------------+------+-----------+
两者之间的唯一区别是 h.type = 'home'
条件的位置 - 第一个是在 where
子句中,第二个是on
子句的一部分。
为什么第二个查询返回的结果与第一个不同?
最佳答案
在第二个 SQL 中,条件 h.type = 'home' 是外连接条件的一部分,而不是对结果的筛选。对于 h.type='cell' 的所有记录,条件 h.type = 'home' 为 FALSE,因此未找到“匹配”c 行 - 因此 c.number 为空,这是您唯一的过滤(WHERE)条件.
在伪代码中,您的第二个 SQL 是这样工作的:
for each row in phone_numbers h /* Note this is ALL home AND cell phones */
select c.number from phone_numbers c
where h.person_id = c.person_id
and h.type = 'home'
and c.type = 'cell';
if c.number is null (i.e. no row found)
display h.*
end if
end loop;
关于sql - 自连接查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/344098/