让我们有两个表
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
在第一种情况下表现为外部联接,在后一种情况下表现为内部联接。但是,我不清楚为什么。
答案 0 :(得分: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
我不知道在SQL Server中相当于left join lateral
的情况。
on true
需要写成on 1=1
。
答案 1 :(得分: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