这里的问题是,
slick uses a LiteralNode(true) as the default join condition.
因此,第二个查询将得到如下结果:
select p.*, a1.*, b.*, a2.*
from Users u
join People p on 1 = 1
left join Addresses a1 on 1 = 1
left join Businesses b on 1 = 1
left join Addresses a2 on u.personId = p.id
and p.addressId = a1.id
and p.businessId = b.id
and b.addressId = a2.id
正如您所看到的,对于每个连接的表,所有期望成为连接条件的条件实际上都是最后一个连接的连接条件的一部分。
为了了解这将如何影响最终结果,让我们将问题简化如下:
create temporary table A (id int primary key);
insert into A values (1), (2);
select a1.id, a2.id, a3.id
from A a1
join A a2 on 1 = 1
left join A a3 on a1.id = a2.id
and a2.id = a3.id;
在第一个连接中,a1和a2由一个始终为true的条件连接,从而产生临时结果:
(1, 1)
(1, 2)
(2, 1)
(2, 2)
现在让我们考虑第二个连接。我们有
a1.id = a2.id
作为连接条件的一部分,但请记住,连接条件用于决定如何从表a3检索行,而不是过滤第一个连接的中间结果。我们在这里进行左连接,因此即使不满足连接条件,也会生成一个额外的3行NULL。最终结果将是:
(1, 1, 1)
(1, 2, NULL)
(2, 1, NULL)
(2, 2, 2)
因此,如果最后一个左连接表的列为NULL,您将看到更多意外的结果。