Oracle SQL 在另一个子查询中使用子查询值

Oracle SQL use subquery value in another subquery

在我继续之前,请注意我对 SQL 没有很好的经验。

我有一个获取单个值(netto 值)的查询,例如:

WITH cte_value_net AS (
    SELECT
        nvl(min(value_net),0) as value_net
    FROM (
        SELECT
            i.serial as serial,
            nvl(lag(i.value_net) OVER (PARTITION BY i.serial ORDER BY i.month), i.value_net) as value_net
        FROM 
            inventory i
        WHERE 
            i.ctypde IN (
                SELECT
                    ctypde
                FROM
                    appar ap
                WHERE 
                    ap.serial = in_serial -- this is the variable I want to set
            )
        AND 
            i.month IN (to_char(add_months(sysdate, -1), 'YYYYMM'), to_char(add_months(sysdate, -2), 'YYYYMM'))
        AND
            i.serial = in_serial -- this is the variable I want to set
    ) vn
    GROUP BY vn.serial
)

在这里,我必须输入我认为可以从另一个子查询获得的变量 in_serial,例如:

SELECT
    (SELECT * FROM cte_value_net) AS value_net
FROM (
    SELECT
        lap.serial AS in_serial
    FROM
        applap lap
)

但我无法理解为什么这个 in_serial 对我的自定义 CTE 不可见。有人可以解释一下如何从这样的子查询中传播值吗?

我明显得到的错误是:

SQL Error [904] [42000]: ORA-00904: "IN_SERIAL"

很遗憾,我没有任何示例数据。我想要实现的是,我可以将 returned in_serial 从主子查询输入到我的 CTE。

在获得 value_net 之前,我需要对 return 和 in_serial 进行主查询,否则我无法访问该值。

首先,您的第二个查询在语法上不正确,因为在 FROM 之前有一个“,”。您可以这样编写查询:

WITH cte_value_net AS (
    SELECT
        serial, nvl(min(value_net),0) as value_net
    FROM (
        SELECT
            i.serial as serial,
            nvl(lag(i.value_net) OVER (PARTITION BY i.serial ORDER BY i.month), i.value_net) as value_net
        FROM 
            inventory i
        WHERE 
            i.ctypde IN (
                SELECT
                    ctypde
                FROM
                    appar ap
                WHERE 
                    ap.serial = i.serial
            )
        AND 
            i.month IN (to_char(add_months(sysdate, -1), 'YYYYMM'), to_char(add_months(sysdate, -2), 'YYYYMM'))
    ) vn
    GROUP BY vn.serial
)
select ...
from cte_value_net s join applap lap on (lap.serial=s.serial)

(根据您的架构调整查询....)

我使用的技巧是生成一个额外的 CTE,我通常将其称为 params,其中包含包含所有计算参数的单行。然后,根据需要在任何其他 CTE、子查询或主查询中使用此 CTE 执行 CROSS JOIN

例如:

with
params as ( -- 1. Create a CTE that returns a single row
  select serial as in_serial from applap
),
cte_value_net AS (
  select ...
  from inventory i
  cross join params -- 2. cross join against the CTE anywhere you need it
  where ...
    and i.serial = params.in_serial -- 3. Use the parameter
)
select ...