为什么聚合函数在 apply 块中不能按预期工作
Why an aggregation function doesn't work as expected in an apply block
WITH
a (v)
AS
( SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL < 5),
b (v)
AS
( SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL < 5)
SELECT a.v
FROM a
CROSS APPLY (SELECT MIN (b.v)
FROM b
WHERE a.v = b.v) bb
结果 1,2,3,4
但预期结果将是 1,1,1,1.
1,2,3,4
是正确的输出。
在外部查询中,您 SELECT a.v
将 select 来自 table a
CROSS JOIN
的 v
值与单行聚合由 CROSS APPLY
.
生成
对于您的代码,CROSS APPLY
中 bb
sub-query 的输出是什么并不重要,因为您没有从 [=18= 输出值] 并且聚合强制输出为单行。
如果您想从 bb
sub-query 中获取值,请使用:
WITH a (v) AS (
SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5
),
b (v) AS (
SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5
)
SELECT a.v, bb.min_v
FROM a
CROSS APPLY (
SELECT MIN (b.v) As min_v
FROM b
WHERE a.v = b.v
) bb
则输出为:
V
MIN_V
1
1
2
2
3
3
4
4
如果您想要所有 1
,那么 SELECT
来自 bb
的值并使用 b.v <= a.v
作为过滤器:
WITH a (v) AS (
SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5
),
b (v) AS (
SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5
)
SELECT a.v, bb.min_v
FROM a
CROSS APPLY (
SELECT MIN (b.v) As min_v
FROM b
WHERE b.v <= a.v
) bb
输出:
V
MIN_V
1
1
2
1
3
1
4
1
db<>fiddle here
我想,一切都按预期进行。您的 cross-apply 被评估为 per-row。
因此,当您将 a.v=1 推到那里时,要评估的查询是
SELECT 最小值 (b.v)
从 b 哪里 1= b.v
然后您提供 a.v=2 并且要评估的查询是
SELECT 最小值 (b.v)
从 b 哪里 2= b.v
WITH
a (v)
AS
( SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL < 5),
b (v)
AS
( SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL < 5)
SELECT a.v
FROM a
CROSS APPLY (SELECT MIN (b.v)
FROM b
WHERE a.v = b.v) bb
结果 1,2,3,4 但预期结果将是 1,1,1,1.
1,2,3,4
是正确的输出。
在外部查询中,您 SELECT a.v
将 select 来自 table a
CROSS JOIN
的 v
值与单行聚合由 CROSS APPLY
.
对于您的代码,CROSS APPLY
中 bb
sub-query 的输出是什么并不重要,因为您没有从 [=18= 输出值] 并且聚合强制输出为单行。
如果您想从 bb
sub-query 中获取值,请使用:
WITH a (v) AS (
SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5
),
b (v) AS (
SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5
)
SELECT a.v, bb.min_v
FROM a
CROSS APPLY (
SELECT MIN (b.v) As min_v
FROM b
WHERE a.v = b.v
) bb
则输出为:
V MIN_V 1 1 2 2 3 3 4 4
如果您想要所有 1
,那么 SELECT
来自 bb
的值并使用 b.v <= a.v
作为过滤器:
WITH a (v) AS (
SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5
),
b (v) AS (
SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5
)
SELECT a.v, bb.min_v
FROM a
CROSS APPLY (
SELECT MIN (b.v) As min_v
FROM b
WHERE b.v <= a.v
) bb
输出:
V MIN_V 1 1 2 1 3 1 4 1
db<>fiddle here
我想,一切都按预期进行。您的 cross-apply 被评估为 per-row。 因此,当您将 a.v=1 推到那里时,要评估的查询是
SELECT 最小值 (b.v) 从 b 哪里 1= b.v
然后您提供 a.v=2 并且要评估的查询是
SELECT 最小值 (b.v) 从 b 哪里 2= b.v