I have been tortured by this issue over the last two weeks and can't spend any more time on it. I would love to hear any ideas from this community, if you have a minute. I'm self taught so I'll have to explain this in lay terms. Thank you for your consideration.
My goal is to fetch all invoices with nonzero balance. This is straightforward enough for regular invoices. The problem arises with payment reminders, because their balance is just the late fee, so in order to fetch their total balance I have to link back to their original invoices through a single field in a connecting table COLLECTIVEINVOICENO
.
Example of table INVOICE
:
invoiceid | invoiceno | invoicetypename | amount
--------------|---------------|---------------------|--------------------
10008 | 123000 | Payment Reminder | 5
10005 | 113000 | Payment Reminder | 5
10001 | 110000 | Invoice | 35
Example of table COLLECTIVEINVOICENO
where 10001
and 10005
are overdue:
invoiceid | followed_up_in (CHAR)
--------------|----------------------------------------------------------
10005 | 113000, 123000
10001 | 113000
I have found a very bad solution, which works to fetch the ledger of a single customer at a time, but it is so demanding of resources there is no way I can use it on the entire table INVOICE
:
select (
select sum(i.amount) as sum
from INVOICE i0
join COLLECTIVEINVOICENO cin0 on cin0.invoiceid = i0.invoiceid
where instr(cin0.followed_up_in, i.invoiceno) > 0
) as original_sum
from INVOICE i
This full table scan is repeated five times in my main select
so as to sort various balances into different columns, and for fetching other data from original invoices besides their balance, such as their locations etc.
My original intention was to left-join the subselect onto INVOICE i
as a view, but there Oracle doesn't recognize i.invoice
in instr(cin0.collectiveinvoiceno, i.invoice)
(ORA-00904: "I"."INVOICENO": invalid identifier).
I am now left to looking into cursors etc., which I am currently doing, but I would really like to know if there are any SQL, non-PL ways about it?
Thank you.
Edit: About splitting the comma-separated data into rows ie. changing the data model to facilitate relations: That would certainly help I'm sure, however the data model is packaged with a third-party software so I can't do anything about it. (I would not be surprised if they do change it at some point though, because it manifests with the end user as a major weakness.)
Edit 2: Have tried splitting the comma-separated data into rows using regexp_substr()
with level
and connect by
and join this view to the main table. I doesn't solve the problem because when I regexp_substr()
is expensive resources-wise when other tables are joined on, and the query doesn't deliver even after half an hour. Google reveals that this is a common problem with regular expressions and one is advised to try stored procedures instead.
I've changed the title to reflect this and I will be grateful on any input on how to solve this using stored procedures. Anyway, thanks!