mik*_*nin 5 sql postgresql join
我有2张桌子:
Devices (id (PK))
Links (id (PK), device_id_1 (FK), device_id_2 (FK))
Run Code Online (Sandbox Code Playgroud)
代表通过链接连接的设备。
我需要选择与给定设备(可以是 device_id_1 或 device_id_2)连接的所有设备。我尝试使用以下查询来做到这一点:
select d2.*
from Devices as d1
left outer join Links as l on d1.id in (l.device_id_1, l.device_id_2)
left outer join Devices as d2 on d2.id in (l.device_id_1, l.device_id_2)
where d1.id = 398 and d2.id <> 398;
Run Code Online (Sandbox Code Playgroud)
但是,一旦我添加第二个JOIN,查询就会返回零行。我究竟做错了什么?
where 子句有效地使您的最后一个左连接成为内部连接。
更正将左联接过滤条件移动到联接条件
select d2.*
from Devices as d1
left outer join Links as l on d1.id in (l.device_id_1, l.device_id_2)
left outer join Devices as d2 on d2.id in (l.device_id_1, l.device_id_2)
and d2.id <> 398
where d1.id = 398;
Run Code Online (Sandbox Code Playgroud)
一种不太优雅但普遍接受的方法是......
select d2.*
from Devices as d1
left outer join Links as l on d1.id in (l.device_id_1, l.device_id_2)
left outer join Devices as d2 on d2.id in (l.device_id_1, l.device_id_2)
where d1.id = 398
and (d2.id <> 398 OR D2.ID is null)
Run Code Online (Sandbox Code Playgroud)
我一般是这么想的。。
使用外连接时,我通常希望在连接发生之前排除行,这样引擎就不必生成如此大的笛卡尔坐标。此外,在外连接上,我想返回空记录。但是,如果我在 where 子句中应用限制,则从外部联接生成的所有空记录都将被删除,除非我也考虑 NULLS。
在这种情况下,由于您使用的是 <>... <> 无法与 null 进行比较,因此它将排除所需的记录,因为您无法对 null 值使用相等性检查。
1 = NULL 返回 NULL 和 1 <> NULL 返回 NULL;因此不是真的
| 归档时间: |
|
| 查看次数: |
8643 次 |
| 最近记录: |