我们有两张桌子
create table A (
fkb int,
groupby int
);
create table B (
id int,
search int
);
insert into A values (1, 1);
insert into B values (1, 1);
insert into B values (2, 1);
那么下面的查询
select B.id, t.max_groupby - B.search diff
from B
cross apply (
select max(A.groupby) max_groupby
from A
where A.fkb = B.id
) t
返回预期结果如下
id diff
---------
1 0
2 NULL
但是,当我将
group by A.fkb
添加到交叉应用程序中时,对应的B
不存在的A.fkb
行消失。select B.id, t.max_groupby - B.search diff
from B
cross apply (
select max(A.groupby) max_groupby
from A
where A.fkb = B.id
group by A.fkb
) t
我在SQL Server和PostgreSQL上进行测试(使用
cross join lateral
而不是cross apply
)。为什么group by
会使行消失?似乎cross apply
在第一种情况下表现为外部连接,在后一种情况下表现为内部连接。但是,我不清楚为什么。 最佳答案
当您单独查看内部查询的结果时,可以看到这一点:
select max(A.groupby) max_groupby
from A
where A.fkb = 2;
返回一行
max_groupby
=空:max_groupby
-----------
(null)
但是,由于没有按其分组的
A.fkb = 2
行会生成空结果,您可以在运行时看到该结果:select max(A.groupby) max_groupby
from A
where A.fkb = 2
group by A.fkb
因此交叉连接不会返回
fkb = 2
的返回行您需要使用外部联接才能包含
B
中的行。在Postgres中,您必须这样写:
select B.id, t.max_groupby - B.search diff
from B
left join lateral (
select max(A.groupby) max_groupby
from A
where A.fkb = B.id
group by A.fkb
) t on true
我不知道在SQL Server中
left join lateral
的等价物是什么。on true
需要写成on 1=1
。