sql - 自连接查询

标签 sql mysql join self-join

考虑下表:

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/

相关文章:

java - jSecurity JDBCRealm SQL 设置

mysql - MariaDB永久变量设置

mysql - 如何在MySQL中进行多个组计数

sql - 如何在一个查询中从一个表中检索记录并从另一个表中检索相关记录?

mysql - 使用字段数据的条件 JOIN

mysql - 从mysql表中删除重复值但保留一个

while 循环 JOIN 中的 PHP SQL 查询

mysql - 根据特定的 meta_key 和 meta_value 过滤帖子元

MySQL:是否可以拥有从属内存数据库?

mysql - UPDATE 比等效的 SELECT 影响更少的行