Question

I have a table interest_summary table with two columns:

  • int_rate number,
  • total_balance number

example

10.25  50
10.50 100
10.75 240
11.00  20

My query should return in 2 columns or a string like 10.50 to 10.75 because adding their total exceed 60% of total amount added together

Could you suggest a logic in Oracle?

Was it helpful?

Solution

select 
  min(int_rate), 
  max(int_rate) 
from 
  (
    select 
      int_rate,   
      nvl(sum(total_balance) over(
        order by total_balance desc
        rows between unbounded preceding and 1 preceding
      ),0) as part_sum
    from interest_summary
  )
where 
  part_sum < (select 0.6*sum(total_balance) from interest_summary)

fiddle

OTHER TIPS

I'm assuming that you're selecting the rows based on the following algorithm:

  1. Sort your rows by total_balance (descending)
  2. Select the highest total_balance row remaining
  3. If its total_balance added to the running total of the total balance is under 60%, add it to the pool and get the next row (step 2)
  4. If not add the row to the pool and return.

The sorted running total looks like this (I'll number the rows so that it's easier to understand what happens):

SQL> WITH data AS (
  2            SELECT 1 id, 10.25 interest_rate,  50 total_balance FROM DUAL
  3  UNION ALL SELECT 2 id, 10.50 interest_rate, 100 total_balance FROM DUAL
  4  UNION ALL SELECT 3 id, 10.75 interest_rate, 240 total_balance FROM DUAL
  5  UNION ALL SELECT 4 id, 11.00 interest_rate,  20 total_balance FROM DUAL
  6  )
  7  SELECT id, interest_rate,
  8         SUM(total_balance) OVER (ORDER BY total_balance DESC) running_total,
  9         SUM(total_balance) OVER (ORDER BY total_balance DESC)
 10         /
 11         SUM(total_balance) OVER () * 100 pct_running_total
 12    FROM data
 13   ORDER BY 3;

        ID INTEREST_RATE RUNNING_TOTAL PCT_RUNNING_TOTAL
---------- ------------- ------------- -----------------
         3         10,75           240  58,5365853658537
         2          10,5           340  82,9268292682927
         1         10,25           390  95,1219512195122
         4            11           410               100

So in this example we must return rows 3 and 2 because row 2 is the first row where its percent running total is above 60%:

SQL> WITH data AS (
  2            SELECT 1 id, 10.25 interest_rate,  50 total_balance FROM DUAL
  3  UNION ALL SELECT 2 id, 10.50 interest_rate, 100 total_balance FROM DUAL
  4  UNION ALL SELECT 3 id, 10.75 interest_rate, 240 total_balance FROM DUAL
  5  UNION ALL SELECT 4 id, 11.00 interest_rate,  20 total_balance FROM DUAL
  6  )
  7  SELECT ID, interest_rate
  8    FROM (SELECT ID, interest_rate,
  9                 SUM(over_limit)
 10                    OVER(ORDER BY total_balance DESC) over_limit_no
 11            FROM (SELECT id,
 12                         interest_rate,
 13                         total_balance,
 14                         CASE
 15                            WHEN SUM(total_balance)
 16                                    OVER(ORDER BY total_balance DESC)
 17                                 / SUM(total_balance) OVER() * 100 < 60 THEN
 18                             0
 19                            ELSE
 20                             1
 21                         END over_limit
 22                    FROM data
 23                   ORDER BY 3))
 24   WHERE over_limit_no <= 1;

        ID INTEREST_RATE
---------- -------------
         3         10,75
         2          10,5
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top