Mysql 在百分位范围内划分数据,并为不同的范围分配不同的值

Mysql 在百分位范围内划分数据,并为不同的范围分配不同的值,mysql,Mysql,我的表结构如下所示 Temp Customer_id | sum 现在,我必须创建具有额外列customer_类型的视图,如果customer位于前10%的customer(按总和降序排列)中,则指定值1;如果customer位于10%-20%之间,则指定值2;如果customer位于20%-60%之间,则指定值3;如果customer位于60%-100%之间,则指定值4。我该怎么做 我只能提取前10%和10%-20%之间的数据,但无法将值指定为 而且效率不高,只需增强上述代码即可 sele

我的表结构如下所示

Temp
 Customer_id | sum
现在,我必须创建具有额外列customer_类型的视图,如果customer位于前10%的customer(按总和降序排列)中,则指定值1;如果customer位于10%-20%之间,则指定值2;如果customer位于20%-60%之间,则指定值3;如果customer位于60%-100%之间,则指定值4。我该怎么做

我只能提取前10%和10%-20%之间的数据,但无法将值指定为

而且效率不高,只需增强上述代码即可

select * from temp t1 
where (select count(*) from temp t2 where t2.sum>=t2.sum)
>= (select 0.1 * count(*) from temp) and (select count(*) from temp t2 where t2.sum>=t1.sum)
<= (select 0.2 * count(*) from temp);

样本数据可在

上找到,这将对您有所帮助。您需要获得总行数和总行数的行号。我相信你能很容易地解决剩下的问题

SELECT  
    *,
    @curRow := @curRow + 1 AS row_number,
    (@curRow2 := @curRow2 + 1) / c as pct_row
FROM    
    temp t
    JOIN (SELECT @curRow := 0) r
    JOIN (SELECT @curRow2 := 0) r2
    join (select count(*) c from temp) s
order by 
    sum desc

这是基于此

这应该对您有所帮助。您需要获得总行数和总行数的行号。我相信你能很容易地解决剩下的问题

SELECT  
    *,
    @curRow := @curRow + 1 AS row_number,
    (@curRow2 := @curRow2 + 1) / c as pct_row
FROM    
    temp t
    JOIN (SELECT @curRow := 0) r
    JOIN (SELECT @curRow2 := 0) r2
    join (select count(*) c from temp) s
order by 
    sum desc

这是基于这个

我已经像这样解决了这个问题。谢谢他的回答,他引导我走到这一步

select customer_id,sum,case 
when pct_row<=0.10 then 1
when pct_row>0.10 and pct_row<=0.20 then 2
when pct_row>0.20 and pct_row<=0.60 then 3
when pct_row>0.60 then 4
end as customer_label from (
select customer_id,sum,(@curRow := @curRow+1)/c as pct_row
from temp t 
jOIN (SELECT @curRow := 0) r
JOIN (SELECT @curRow2 := 0) r2 
join (select count(*) c from temp) s
order by sum desc) p;

我不知道这是否是一种有效的方法,但对于小数据集来说效果很好。

我已经像这样解决了这个问题。谢谢他的回答,他引导我走到这一步

select customer_id,sum,case 
when pct_row<=0.10 then 1
when pct_row>0.10 and pct_row<=0.20 then 2
when pct_row>0.20 and pct_row<=0.60 then 3
when pct_row>0.60 then 4
end as customer_label from (
select customer_id,sum,(@curRow := @curRow+1)/c as pct_row
from temp t 
jOIN (SELECT @curRow := 0) r
JOIN (SELECT @curRow2 := 0) r2 
join (select count(*) c from temp) s
order by sum desc) p;

我不知道这是否是一种有效的方法,但对于小数据集来说效果很好。

我的观点是这样的,但我认为这不是一种很好的视图使用方法。这是一个相当密集的操作,我不希望每次有人访问视图时都运行它。相反,我会用这些信息添加一个新表,并在每天凌晨用脚本填充它,这样您的数据可能不是实时的,但足够接近,在需要时可以非常高效地抓取。@我同意您的看法。但我目前正在做数据分析,我创建视图只是为了临时…也许在这里放一些样本数据50条记录左右,可能会更容易得到帮助。@dspear我已经添加了数据…只是我的意见,但我认为这不是视图的好用。这是一个相当密集的操作,我不希望每次有人访问视图时都运行它。相反,我会用这些信息添加一个新表,并在每天凌晨用脚本填充它,这样您的数据可能不是实时的,但足够接近,在需要时可以非常高效地抓取。@我同意您的看法。但我目前正在做数据分析,我创建Views只是为了暂时…也许在这里放一些样本数据,大约50条记录,这样可能更容易获得帮助。@pear我已经添加了数据。。。