交叉应用中的 GROUP BY
GROUP BY in CROSS APPLY
让我们有两个表
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
return预期结果如下
id diff
---------
1 0
2 NULL
但是,当我将 group by 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 服务器和 PostgreSQL 上进行测试(使用 cross join lateral
而不是 cross apply
)。为什么 group by
使该行消失? cross apply
似乎在第一种情况下表现为外部连接,在后一种情况下表现为内部连接。但是,我不清楚为什么。
发生这种情况是因为:
GROUP BY
returns A.fkb = 2
什么都没有
- 没有
GROUP BY
returns NULL
所以你的查询 CROSS APPLY
returns 不同的结果。
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;
returns 单行 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
因此交叉联接不会 return return 行 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 lateral
在 SQL 服务器中的等价物是什么。
on true
需要写成 on 1=1
.
让我们有两个表
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
return预期结果如下
id diff
---------
1 0
2 NULL
但是,当我将 group by 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 服务器和 PostgreSQL 上进行测试(使用 cross join lateral
而不是 cross apply
)。为什么 group by
使该行消失? cross apply
似乎在第一种情况下表现为外部连接,在后一种情况下表现为内部连接。但是,我不清楚为什么。
发生这种情况是因为:
GROUP BY
returnsA.fkb = 2
什么都没有
- 没有
GROUP BY
returns NULL
所以你的查询 CROSS APPLY
returns 不同的结果。
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;
returns 单行 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
因此交叉联接不会 return return 行 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 lateral
在 SQL 服务器中的等价物是什么。
on true
需要写成 on 1=1
.