0

我有一个interest_summary包含两列的表格:

  • int_rate数字,
  • total_balance数字

例子

10.25  50
10.50 100
10.75 240
11.00  20

我的查询应返回 2 列或 10.50 到 10.75 之类的字符串,因为它们的总和超过加在一起总金额的 60%

你能在Oracle中提出一个逻辑吗?

4

2 回答 2

2
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)

小提琴

于 2013-05-22T09:33:01.870 回答
1

我假设您正在根据以下算法选择行:

  1. total_balance按(降序)对行进行排序
  2. total_balance选择剩余的最高行
  3. 如果其total_balance添加到总余额的运行总计中低于 60%,则将其添加到池中并获取下一行(步骤 2)
  4. 如果没有将该行添加到池中并返回。

排序后的运行总计如下所示(我将对行进行编号,以便更容易理解发生了什么):

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

所以在这个例子中,我们必须返回第 3 行和第 2 行,因为第 2 行是第一行,其百分比运行总计高于 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
于 2013-05-22T09:33:18.477 回答