Sql 根据行的百分比指定列值

Sql 根据行的百分比指定列值,sql,db2,Sql,Db2,在DB2中,有没有一种方法可以根据行的前x%,然后y%和剩余的z%分配列值 我尝试过使用行数函数,但没有成功 下面的例子 假设下面的示例countid已按降序排列 输入: 输出: 上述输入的前30%的行应分配代码H,最后30%的行将分配代码L,其余的行将分配代码M。如果30%的行计算为十进制,则四舍五入至小数点后0位 ID code 5 H 3 H 1 M 4 L 2 L 您可以使用窗口功能: select t.id,

在DB2中,有没有一种方法可以根据行的前x%,然后y%和剩余的z%分配列值

我尝试过使用行数函数,但没有成功

下面的例子 假设下面的示例countid已按降序排列 输入:

输出: 上述输入的前30%的行应分配代码H,最后30%的行将分配代码L,其余的行将分配代码M。如果30%的行计算为十进制,则四舍五入至小数点后0位

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

您可以使用窗口功能:

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
试试这个:

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;

向我们显示您使用行号的代码。
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