为什么聚合函数在 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.

code

1,2,3,4 是正确的输出。

在外部查询中,您 SELECT a.v 将 select 来自 table a CROSS JOINv 值与单行聚合由 CROSS APPLY.

生成

对于您的代码,CROSS APPLYbb 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