获得前n个记录,每个组占> = 90%的金额

时间:2014-07-07 19:39:21

标签: mysql aggregation

我最近在这里阅读并实现了类似问题的答案,并希望看看它是否可以更进一步。

Link to original question

使用类似的样本数据集:

+--------+-------+---+
| ID | Group | Amount|
+--------+-------+---+
| 1  | 1     | 50    |
| 2  | 1     | 25    |
| 3  | 1     | 15    |
| 4  | 1     | 10    |
| 5  | 1     | 0     |
| 6  | 1     | 0     |
| 7  | 2     | 60    |
| 8  | 2     | 20    |
| 9  | 2     | 10    |
| 10 | 2     | 5     |
| 11 | 2     | 5     |
| 12 | 2     | 0     |
| 13 | 3     | 90    |
| 14 | 3     | 10    |
+--------+-------+---+

使用下面列出的代码(感谢前一个问题的@Bluefeet),结果如下:

+--------+-------+---+
| 1   | 1     | 50   |
| 2   | 1     | 25   |
| 7   | 2     | 60   |
| 8   | 2     | 20   |
| 13  | 3     | 90   |
| 14  | 3     | 10   |
+--------+-------+---+

set @num := 0, @group := '';

select id, `group`, amount
from 
(
   select id, `group`, amount,
      @num := if(@group = `group`, @num + 1, 1) as row_number,
      @group := `group` as dummy
  from mytable
  order by `Group`, amount desc, id
) as x 
where x.row_number <= 2;

我想要做的是按照Amount desc选择ID,直到&gt; =满足该组的90%贡献。理想情况下,它应该如下所示:

+--------+-------+---+
| 1   | 1     | 50   |
| 2   | 1     | 25   |
| 3   | 1     | 15   |    
| 7   | 2     | 60   |
| 8   | 2     | 20   |
| 9   | 2     | 10   |
| 13  | 3     | 90   |
+--------+-------+---+

请注意每组的每个组的金额总和为90(此示例中每组的金额加起来为100)。

提前致谢,如果有更多可能有帮助的信息,请与我们联系。

1 个答案:

答案 0 :(得分:0)

据推测,你的意思是“金额”总和的90%。首先累计amount

  select id, `group`, amount,
         @cumsum := if(@group = `group`, @cumsum + amount, 0) as cumsum,
         @group := `group` as dummy
  from mytable
  order by `Group`, amount desc, id

然后,您需要每组的总计进行90%计算。让我们通过将此查询加入聚合查询来执行此操作:

select id, `group`, amount, cumsum
from (select id, `group`, amount,
             @cumsum := if(@group = `group`, @cumsum + amount, 0) as cumsum,
             @group := `group` as dummy
      from mytable
      order by `Group`, amount desc, id
     ) t join
     (select `group`, sum(amount) as tot
      from mytable
      group by `group`
     ) tg
     on t.`group` = tg.`group`
where cum <= 0.9 * tot;

或者,如果您想要 90%之后的第一个值,请使用:

where (cumsum - amount) < 0.9 * tot