Want subquery to return non-Null values

Want subquery to return non-Null values

Problem Description:

I have three tables I am using in a query; AP_INVOICES_INTERFACE , AP_INVOICE_LINES_INTERFACE , and PO_HEADERS_ALL as a subquery.

The AP_INVOICE_LINES_INTERFACE table is joined to PO_HEADERS_ALL only on the PO_NUMBER from AP_INVOICE_LINES_INTERFACE to the SEGMENT1 in PO_HEADERS_ALL. I want to populate the column ‘REQ_BU_ID2’ with the REQ_BU_ID value based on SEGMENT1 equaling LN.PO_NUMBER where it is not NULL.

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

I want to populate the REQ_BU_ID2 (non-null) value for rows even when the LN.PO_NUMBER is NULL so I thought by using the AND LN.PO_NUMBER IS NOT NULL condition in the Subquery would then only return the non-null value, however as you can see it is still returning Null as well in the results:

Current Results from above query:

enter image description here

Desired Results:
enter image description here

Edit:

INVOICE_ID        REQ_BU_ID2        PO_NUMBER   LN_PO_NUMBER
300000136747640   300000006290049               K11004499
300000136747640
300000136747640
300000136747640   300000006290049               K11004499

Solution – 1

The below uses a CTE to give all INVOICE_IDs the same LN_PO_NUMBER.

If they can legitimately ever have different "non-NULL" PO_NUMBERs, this won’t work.

Then your sub-query has been adapted to use ORDER BY REQ_BU_ID DESC FETCH NEXT 1 ROWS ONLY in order to find exactly one REQ_BU_ID in a deterministic way, preferring non-NULL values.

Again, if any PO_NUMBER can legitimately relate to more than 1 non-NULL REQ_BU_ID, this won’t work.

Also, if ZERO REQ_BU_ID are found, it still returns NULL.

WITH
  PO_LOOKUP
AS
(
  SELECT
    HDR.INVOICE_ID,
    HDR.PO_NUMBER,
    MAX(LN.PO_NUMBER) OVER (PARTITION BY HDR.INVOICE_ID)   AS LN_PO_NUMBER
  FROM
    AP_INVOICES_INTERFACE        HDR
  INNER JOIN
    AP_INVOICE_LINES_INTERFACE   LN
      ON LN.INVOICE_ID = HDR.INVOICE_ID
)
SELECT
  PO_LOOKUP.*,
  (
    SELECT REQ_BU_ID
      FROM PO_HEADERS_ALL
     WHERE SEGMENT1 = PO_LOOKUP.LN_PO_NUMBER
  ORDER BY REQ_BU_ID ASC
     FETCH NEXT 1 ROWS ONLY
  )
    AS REQ_BU_ID
FROM
  PO_LOOKUP
WHERE
  INVOICE_ID = 300000136747640

Demo : https://dbfiddle.uk/N9fb6W9I

EDIT: Alternatively…

SELECT
  HDR.INVOICE_ID,
  HDR.PO_NUMBER,
  LN.MAX_PO_NUMBER,
  PO.MAX_REQ_BU_ID
FROM
  AP_INVOICES_INTERFACE        HDR
INNER JOIN
(
  SELECT
    AP_INVOICE_LINES_INTERFACE.*,
    MAX(PO_NUMBER) OVER (PARTITION BY INVOICE_ID)  AS MAX_PO_NUMBER
  FROM
    AP_INVOICE_LINES_INTERFACE
)
  LN
    ON LN.INVOICE_ID = HDR.INVOICE_ID
INNER JOIN
(
  SELECT
    SEGMENT1,
    MAX(REQ_BU_ID)   AS MAX_REQ_BU_ID
  FROM
    PO_HEADERS_ALL
  GROUP BY
    SEGMENT1
)
  PO
    ON PO.SEGMENT1 = LN.MAX_PO_NUMBER
WHERE
  HDR.INVOICE_ID = 300000136747640
Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject