2

让我们有两张桌子

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在第一种情况下表现为外连接,在后一种情况下表现为内连接。但是,我不清楚为什么。

4

2 回答 2

3

当您单独查看内部查询的结果时,您可以看到这一点:

select max(A.groupby) max_groupby
from A 
where A.fkb = 2;

max_groupby返回带有= null的单行:

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

我不知道left join lateralSQL Server 中的等价物是什么。
on true需要写成on 1=1.

于 2019-04-11T07:55:39.997 回答
1

它发生是因为:

  • GROUP BY什么时候不返回A.fkb = 2
  • GROUP BY返回 NULL

因此,您的查询CROSS APPLY返回不同的结果。

select B.id, t.max_groupby - B.search diff
from B
outer apply ( 
  select max(A.groupby) max_groupby
  from A 
  where A.fkb = B.id 
  group by A.fkb
) t

输出:

id  diff
1   0
2   NULL
于 2019-04-11T07:49:31.710 回答