Select 总和值 = 总计 80% 的行

Select Rows who's Sum Value = 80% of the Total

这是业务问题的示例。

我有 10 次销售导致利润为负。 我们要审查这些记录,我们通常在审查中使用 20/80 规则。 也就是说,销售额的 20% 可能占负利润率的 80%。

所以有了下面的记录....

+----+-------+
| ID | Value |
+----+-------+
|  1 |    30 |
|  2 |    30 |
|  3 |    20 |
|  4 |    10 |
|  5 |     5 |
|  6 |     5 |
|  7 |     2 |
|  8 |     2 |
|  9 |     1 |
| 10 |     1 |
+----+-------+

我想return...

+----+-------+
| ID | Value |
+----+-------+
|  1 |    30 |
|  2 |    30 |
|  3 |    20 |
|  4 |    10 |
+----+-------+

总值是106,那么80%就是84.8。 我需要所有记录,按降序排序谁的总和值至少达到 84.8

我们使用 Microsoft APS PDW SQL,但如果需要可以在 SMP 上处理。

假设支持window个函数,你可以使用

with cte as (select id,value
             ,sum(value) over(order by value desc,id) as running_sum 
             ,sum(value) over() as total
             from tbl
            ) 
select id,value from cte where running_sum < total*0.8
union all
select top 1 id,value from cte where running_sum >= total*0.8 order by value desc

一种方法是使用 运行 总数:

select
  id,
  value
from
(
  select
    id,
    value,
    sum(value) over () as total,
    sum(value) over (order by value desc) as till_here,
    sum(value) over (order by value desc rows between unbounded preceding and 1 preceding)
      as till_prev
  from mytable
) summed_up
where till_here * 1.0 / total <= 0.8
   or (till_here * 1.0 / total >= 0.8 and coalesce(till_prev, 0) * 1.0 / total < 0.8)
order by value desc;

这个 link 可能有用,它计算 运行 总数:

https://www.codeproject.com/Articles/300785/Calculating-simple-running-totals-in-SQL-Server