I have the following Oracle SQL in a report that I inherited. The bucket1_days_prc
and overdue_prc
should show the percentage of the number of invoices that falls within those buckets based on the number of days overdue. I haven’t worked with windowing functions in ages, so I can’t figure out how to incorporate the case
date range into the windowing function. Currently the value just divides by itself (although it apparently worked before) and always gives 100%. How can I identify the number of invoices that fall in the bucket for that case
date range and divide it by the total number of invoices? The columns must basically repeat the answer or show null in order to work with BI Publisher (I hope).
select initcap(pv.vendor_name) vendor_name, aia.invoice_num invoice_number, aia.invoice_amount, to_char(aia.invoice_received_date, 'DD-MON-YYYY') invoice_received_date, to_char(aia.invoice_received_date + 30, 'DD-MON-YYYY') date_invoice_due_payment, ( case when (trunc(sysdate) - ((trunc(aia.invoice_received_date)) + 30)) < 0 then 0 else (trunc(sysdate) - ((trunc(aia.invoice_received_date)) + 30)) end ) days_late, ( case when round(trunc(sysdate) - (trunc(aia.invoice_received_date))) between 0 and 9 then aia.invoice_amount end ) bucket1_days, ( case when round(trunc(sysdate) - (trunc(aia.invoice_received_date))) between 0 and 9 then sum(aia.invoice_amount) over (partition by pv.vendor_id order by pv.vendor_id) end ) bucket1_days_sup, nvl ( case when round(trunc(sysdate) - (trunc(aia.invoice_received_date))) between 0 and 9 then count(aia.invoice_id) over (partition by null) / count(aia.invoice_id) over (partition by null) * 100 end, 0 ) bucket1_days_prc, ( case when round(trunc(sysdate) - (trunc(aia.invoice_received_date))) > 30 then aia.invoice_amount end ) overdue, ( case when round(trunc(sysdate) - (trunc(aia.invoice_received_date))) > 30 then sum(aia.invoice_amount) over (partition by pv.vendor_id order by pv.vendor_id) end ) overdue_sup, ( case when round(trunc(sysdate) - (trunc(aia.invoice_received_date))) > 30 then count(aia.invoice_id) over (partition by null) / count(invoice_id) over (partition by null) end ) overdue_prc, sum(invoice_amount) over (partition by pv.vendor_id order by pv.vendor_id) total_per_supplier, count(1) over (partition by pv.vendor_id order by pv.vendor_id) inv_per_supplier, count(invoice_id) over (partition by null) total_inv_cnt, sum(invoice_amount) over (partition by null) total_inv_amt, (sum(invoice_amount) over (partition by pv.vendor_id order by pv.vendor_id) / sum(invoice_amount) over (partition by null)) * 100 total_perc_amt, (count(invoice_amount) over (partition by pv.vendor_id order by pv.vendor_id) / count(invoice_amount) over (partition by null)) * 100 total_perc_cnt from apps.ap_invoices_all aia, apps.gl_periods gp, apps.po_vendors pv where aia.payment_status_flag = 'N' and aia.cancelled_date is null and (trunc(sysdate) - ((aia.invoice_received_date))) > 0 and upper(gp.period_name) = upper(to_char(aia.invoice_received_date, 'MON-YY')) and pv.vendor_id = aia.vendor_id order by 2
The percentage of data in each bucket is needed, so if there is two invoices out of four total in the 0-9 days bucket then that would be 50%.
Sample data and expected output
Advertisement
Answer
Managed to fix it with:
sum ( case when round(trunc(sysdate) - (trunc(aia.invoice_received_date))) between 28 and 30 then 1 else 0 end ) over (partition by null) / sum(1) over (partition by null) bucket7_days_cnt,