考虑下表:
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
子句的一部分。
为什么第二个查询不会返回与第一个查询相同的结果?
答案 0 :(得分:7)
在第二个SQL中,条件h.type ='home'是外连接条件的一部分,并不是结果的过滤器。对于h.type ='cell'的所有记录,条件h.type ='home'为FALSE,因此找不到“匹配”c行 - 所以c.number为null,这是您唯一的过滤(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;
答案 1 :(得分:2)
当做左连接时,我以这种方式处理事物。在连接中,您需要指定实际将两个表链接在一起的anny字段以及来自连接的右侧(连接中的第二个表)的任何过滤条件(有一个例外,我将很快得到)。从连接左侧(第一个表)的过滤条件应该在where子句中,否则它们会在你看到的时候错误地影响连接(并且Tony很好地解释了)。连接的右侧应该在where子句中的唯一时间是,如果要在该表中查找空值(即,第一个表中的记录而不是第二个表中的记录)。
答案 2 :(得分:0)
SEL *
FROM phone_numbers T1
WHERE typeS='home' AND person_id NOT IN
(SELECT person_id FROM phone_numbers T2 WHERE T1.person_id=T2.person_id AND typeS='cell')
答案 3 :(得分:0)
您可以尝试此查询,我希望它对您有用。
select * from phone_numbers
where person_id not in (select person_id from phone_numbers where type='cell')
答案 4 :(得分:-2)
我不知道这是否会解决问题,但是......
以“and”开头的语句应该是WHERE子句的一部分,而不是ON子句的一部分。 ON子句应仅具有涉及使用哪些列来连接表的语句。