如何找到销售总额超过60%的地区

时间:2013-05-22 09:10:11

标签: sql oracle analytical

我有一个包含两列的表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中建议一个逻辑吗?

2 个答案:

答案 0 :(得分: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)

fiddle

答案 1 :(得分:1)

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

  1. total_balance(降序)
  2. 对行进行排序
  3. 选择剩余的最高total_balance
  4. 如果将total_balance添加到总余额的总计不到60%,请将其添加到池中并获取下一行(第2步)
  5. 如果没有将行添加到池中并返回。
  6. 已排序的运行总计看起来像这样(我会对行进行编号,以便更容易理解会发生什么):

    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