You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让子查询返回非空值?Oracle财务表关联查询问题

问题描述

我在查询中用到三张表:AP_INVOICES_INTERFACE、AP_INVOICE_LINES_INTERFACE,并将PO_HEADERS_ALL作为子查询。其中AP_INVOICE_LINES_INTERFACE只能通过自身的PO_NUMBER与PO_HEADERS_ALL的SEGMENT1字段关联。我的需求是用REQ_BU_ID的值填充REQ_BU_ID2列,填充条件是SEGMENT1等于非空的LN.PO_NUMBER。

当前使用的查询语句如下:

SELECT HDR.INVOICE_ID  , HDR.PO_NUMBER , LN.PO_NUMBER LN_PO_NUMBER

, (SELECT PO2.REQ_BU_ID
    FROM PO_HEADERS_ALL PO2
    WHERE PO2.SEGMENT1 = LN.PO_NUMBER
       AND PO2.REQ_BU_ID IS NOT NULL
       AND LN.PO_NUMBER IS NOT NULL
       --AND HDR.PO_NUMBER IS NOT NULL
       AND rownum = 1    ) REQ_BU_ID2

FROM AP_INVOICES_INTERFACE HDR
INNER JOIN AP_INVOICE_LINES_INTERFACE LN ON LN.INVOICE_ID = HDR.INVOICE_ID
AND HDR.INVOICE_ID = 300000136747640

我原本希望就算LN.PO_NUMBER为空,REQ_BU_ID2也能填充非空值,以为在子查询里加AND LN.PO_NUMBER IS NOT NULL就能实现,但结果还是出现了NULL值。

补充数据示例:

INVOICE_ID        REQ_BU_ID2        PO_NUMBER   LN_PO_NUMBER
300000136747640   300000006290049               K11004499
300000136747640
300000136747640
300000136747640   300000006290049               K11004499
解决方案

问题根源在于子查询逻辑:当LN.PO_NUMBER为空时,AND LN.PO_NUMBER IS NOT NULL这个条件会直接让子查询返回空结果,导致REQ_BU_ID2为NULL。要实现空值时也填充非空值,你需要明确空值场景下的取值规则,以下两种常见场景的解决方案:

场景1:复用同发票下其他行的有效REQ_BU_ID

如果希望某行LN.PO_NUMBER为空时,直接使用同一张发票下其他行已获取到的非空REQ_BU_ID,可以用窗口函数实现:

SELECT 
    HDR.INVOICE_ID, 
    HDR.PO_NUMBER, 
    LN.PO_NUMBER LN_PO_NUMBER,
    -- 取同发票下所有有效REQ_BU_ID中的任意非空值,MAX/MIN/ANY_VALUE均可
    MAX(PO2.REQ_BU_ID) OVER (PARTITION BY HDR.INVOICE_ID) REQ_BU_ID2
FROM AP_INVOICES_INTERFACE HDR
INNER JOIN AP_INVOICE_LINES_INTERFACE LN 
    ON LN.INVOICE_ID = HDR.INVOICE_ID
LEFT JOIN PO_HEADERS_ALL PO2
    ON PO2.SEGMENT1 = LN.PO_NUMBER
    AND PO2.REQ_BU_ID IS NOT NULL
WHERE HDR.INVOICE_ID = 300000136747640;

场景2:空值时用表头的PO_NUMBER关联

如果希望LN.PO_NUMBER为空时,改用HDR.PO_NUMBER去关联PO_HEADERS_ALL获取REQ_BU_ID,可以用COALESCE函数调整关联条件:

SELECT 
    HDR.INVOICE_ID, 
    HDR.PO_NUMBER, 
    LN.PO_NUMBER LN_PO_NUMBER,
    (SELECT PO2.REQ_BU_ID
     FROM PO_HEADERS_ALL PO2
     WHERE PO2.SEGMENT1 = COALESCE(LN.PO_NUMBER, HDR.PO_NUMBER)
       AND PO2.REQ_BU_ID IS NOT NULL
       AND rownum = 1) REQ_BU_ID2
FROM AP_INVOICES_INTERFACE HDR
INNER JOIN AP_INVOICE_LINES_INTERFACE LN 
    ON LN.INVOICE_ID = HDR.INVOICE_ID
WHERE HDR.INVOICE_ID = 300000136747640;

逻辑说明

  • 场景1中,窗口函数会将同一张发票下所有行的有效REQ_BU_ID进行聚合,确保每行都能拿到非空值(只要该发票下存在至少一个有效关联)。
  • 场景2中,COALESCE函数会优先使用行级的LN.PO_NUMBER,为空时自动切换为表头的HDR.PO_NUMBER,保证子查询能找到匹配的REQ_BU_ID。

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:05:21