Skip to content
Advertisement

Oracle – How to partition by case statement

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

enter image description here

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,                   
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement