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:
Edit:
INVOICE_ID REQ_BU_ID2 PO_NUMBER LN_PO_NUMBER
300000136747640 300000006290049 K11004499
300000136747640
300000136747640
300000136747640 300000006290049 K11004499
CodePudding user response:
The below uses a CTE to give all INVOICE_ID
s the same LN_PO_NUMBER
.
If they can legitimately ever have different "non-NULL" PO_NUMBER
s, 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