根据行的百分比分配列值

时间:2019-05-21 12:30:20

标签: sql db2

在DB2中,有一种方法可以基于行的前x%,y%和其余z%来分配列值?

我尝试使用row_number()函数,但是没有运气!

下面的例子 假设下面的示例count(id)已经按降序排列 输入:

ID   count(id)
5       10 
3        8
1        5
4        3
2        1

输出: 上面输入的前30%行应分配为代码H,后30%的行应分配为代码L,其余的行将分配为代码M。如果30%的行求值为小数,则四舍五入至小数点后0位。

ID     code
5       H
3       H
1       M
4       L
2       L

2 个答案:

答案 0 :(得分:1)

您可以使用窗口功能:

select t.id,
       (case ntile(3) over (order by count(id) desc) 
            when 1 then 'H'
            when 2 then 'M'
            when 3 then 'L'
        end) as grp
from t
group by t.id;

这会将它们分成大小相等的组。

要根据情况将收入分成30-40-30%,您必须格外小心:

select t.id,
       (case when (seqnum - 1.0) < 0.3 * cnt then 'H'
             when (seqnum + 1.0) > 0.7 * cnt then 'L'
             else 'M'
        end) as grp
from (select t.id,
             count(*) as cnt,
             count(*) over () as num_ids,
             row_number() over (order by count(*) desc) as seqnum
      from t
      group by t.id
     ) t

答案 1 :(得分:0)

尝试一下:

with t(ID, count_id) as (values
  (5, 10)
, (3, 8)
, (1, 5)
, (4, 3)
, (2, 1)
)
select t.*
, case 
    when pst <=30 then 'H'
    when pst <=70 then 'M'
    else 'L'
  end as code
from 
(
  select t.*
  , rownumber() over (order by count_id desc) as rn
  , 100*rownumber() over (order by count_id desc)/nullif(count(1) over(), 0) as pst
  from t
) t;

结果是:

ID COUNT_ID RN PST CODE
-- -------- -- --- ----
 5       10  1  20 H
 3        8  2  40 M
 1        5  3  60 M
 4        3  4  80 L
 2        1  5 100 L