Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 交叉申请中的分组_Sql_Sql Server_Postgresql_Lateral Join - Fatal编程技术网

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