Home > database >  Oracle - How to join multiple Tables with same FK and no other correlation between them
Oracle - How to join multiple Tables with same FK and no other correlation between them

Time:02-11

I'm Making a Query to get the Payments of a Invoice. But since i can have, multiple cards, Accounts Receivable and Money (cash and change). is it possible to make this work without using function, Unions and subqueries? all tables have 300k records, and i want to make a view for ease of use/maintain. however when i use union on views perfromance drops drastically

THE FOLLOWING EXEMPLE

Invoice

INVOICE
113806

Invoice -> entry

INVOICE ID_ENTRY
113806 387473

Accounts Receivable

ID_ENTRY ID_AR DUE TO
387473 31014 15/05/2022
387473 31015 15/06/2022

Card

ID_ENTRY ID_CARD DUE TO
387473 407214 01/01/2022

Cash

ID_ENTRY ID_CASH VALUE
387473 407214 10
387473 407215 -5

Query

SELECT NAF.INVOICE_ENTRY, ADRE.ID_AR, ACAR.ID_CARD, ADIN.ID_CASH
FROM INVOICE N
INNER JOIN INVOICE_ENTRY NAF
    ON NAF.ID_INVOICE = N.ID_INVOICE
LEFT JOIN AR_ENTRY ADRE
    ON ADRE.ID_ENTRY = NAF.ID_ENTRY
LEFT JOIN CARD_ENTRY ACAR
    ON ACAR.ID_ENTRY = NAF.ID_ENTRY
LEFT JOIN CASH_ENTRY ADIN
    ON ADIN.ID_ENTRY = NAF.ID_ENTRY
WHERE N.ID_INVOICE = :ID_INVOICE 

Result

ID_ENTRY ID_AR ID_CARD ID_CASH
387473 31014 221396 407214
387473 31014 221396 407215
387473 31015 221396 407214
387473 31015 221396 407215

Expected Result

ACERFIN IDAD IDCAR IDDIN
387473 31014 NULL NULL
387473 31015 NULL NULL
387473 NULL 221396 NULL
387473 NULL NULL 407214
387473 NULL NULL 407215

Conclusion: The desired Result can't be achieved by a simple query, the use of Unions is necessary.

Note: My question was to try a workaround for performance issues. However it would be a diferent question.

CodePudding user response:

You can use UNION ALL on the accounts_receivable, cash and card tables and then join the result to the other tables:

SELECT u.*
FROM   invoice i
       INNER JOIN entry e
       ON (i.invoice = e.invoice)
       INNER JOIN (
         SELECT id_entry AS acerfin, id_ar AS idad, NULL AS idcar, NULL AS iddin
         FROM   accounts_receivable
         UNION ALL
         SELECT id_entry, NULL, id_card, NULL
         FROM   card
         UNION ALL
         SELECT id_entry, NULL, NULL, id_cash
         FROM   cash
       ) u
       ON (e.id_entry = u.acerfin)
WHERE  i.invoice = 113806

Which, for the sample data:

CREATE TABLE invoice (INVOICE) AS
SELECT 113806 FROM DUAL;

CREATE TABLE entry (INVOICE, ID_ENTRY) AS
SELECT 113806, 387473 FROM DUAL;

CREATE TABLE Accounts_Receivable (ID_ENTRY, ID_AR, DUE_TO) AS
SELECT 387473, 31014, DATE '2022-05-15' FROM DUAL UNION ALL
SELECT 387473, 31015, DATE '2022-06-15' FROM DUAL;

CREATE TABLE Card (ID_ENTRY, ID_CARD, DUE_TO) AS
SELECT 387473, 407214, DATE '2022-05-01' FROM DUAL;

CREATE TABLE Cash (ID_ENTRY, ID_CASH, VALUE) AS
SELECT 387473, 407214, 10 FROM DUAL UNION ALL
SELECT 387473, 407215, -5 FROM DUAL;

Outputs:

ACERFIN IDAD IDCAR IDDIN
387473 31014 null null
387473 31015 null null
387473 null 407214 null
387473 null null 407214
387473 null null 407215

db<>fiddle here

  • Related