我们有两张桌子

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

07-24 09:19