Sql 交叉申请中的分组
我们要两张桌子Sql 交叉申请中的分组,sql,sql-server,postgresql,lateral-join,Sql,Sql Server,Postgresql,Lateral Join,我们要两张桌子 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
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
但是,当我将A.fkb的组添加到交叉应用中时,对应A.fkb不存在的B行将消失
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上进行了测试,使用交叉连接而不是交叉应用。为什么“分组方式”会使行消失?在第一种情况下,交叉应用的行为似乎是外部连接,在后一种情况下是内部连接。但是,我不清楚原因。发生这种情况是因为:
当A.fkb=2时,GROUP BY不返回任何内容
没有GROUPBY返回NULL
因此,您的查询交叉应用将返回不同的结果
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
单独查看内部查询的结果时可以看到:
select max(A.groupby) max_groupby
from A
where A.fkb = 2;
返回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中,左连接的等价物是什么。on true需要写成on 1=1。谢谢您的回答。我的问题是:为什么交叉申请中的分组会对结果产生影响?换句话说,为什么要通过改变组的语义来引入连接?回答得很好,谢谢!SQL Server中左连接的等效项是outer apply.select B.id,从A中选择maxA.groupby,其中A.fkb=B.id-B.search diff from B我想您应该会得到这个查询的结果。
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