前言
实际工作中对范围分组统计的需求还是相对普遍的,本文记录下在mysql中通过函数和sql完成分组统计的实现过程。
数据及期望
比如我们获取到了豆瓣电影top250,现在想知道各个分数段的电影总数.
表数据如下:
期望结果:
实现方案
主要思路是根据score的范围设置别名,然后按照别名统计即可。
方案一:
sql
select tmp.level, count(1) as cnt from
(select
score,
case
when score >= 7 and score < 8 then '[7,8)'
when score >= 8 and score < 8.5 then '[8,8.5)'
when score >= 8.5 and score < 9 then '[8.5,9)'
when score >= 9 and score < 9.5 then '[9,9.5)'
when score >= 9.5 and score < 10 then '[9.5,10)'
end as level
from `douban_movie_top250` limit 20 ) tmp
group by tmp.level
order by tmp.level asc
方案二:
mysql
select
case tmp.level
when 1 then '[7,8)'
when 2 then '[8,8.5)'
when 3 then '[8.5,9)'
when 4 then '[9,9.5)'
when 5 then '[9.5,10)'
end as level, count(1) as cnt
from
(select score, interval(score, 7, 8, 8.5, 9, 9.5) as level from `douban_movie_top250` limit 20) tmp
group by tmp.level
order by tmp.level asc
INTERVAL()函数介绍
INTERVAL()函数可以返回分段后的结果,语法如下:
INTERVAL(N,N1,N2,N3,...)
其中,N是要判断的数值,N1,N2,N3,...是分段的间隔。
sql中用到了interval
函数,interval(score, 7, 8, 8.5, 9, 9.5)
返回的是score所处阶段的索引,比如返回1代表score在[7,8)范围内,前闭后开,依次类推。
分数段 | 对应值 |
---|---|
[7,8) | 1 |
[8,8.5) | 2 |
[8.5,9) | 3 |
[9,9.5) | 4 |
[9.5,10) | 5 |
我们直接查询下这个函数使用的结果验证下:
sql
select score, interval(score, 7, 8, 8.5, 9, 9.5) as level
from `douban_movie_top250` limit 20
结果如下:
可以看到验证结果是正确的,依据这个特性还是可以做不少事情的。
方案三:
sql
select level, count(1) as cnt from (
select score, elt(interval(score, 7, 8, 8.5, 9, 9.5), '[7,8)','[8,8.5)', '[8.5,9)', '[9,9.5)','[9.5,10)') as level
from `douban_movie_top250` limit 20) tmp
group by tmp.level order by tmp.level asc;
这个sql中用到了elt
函数和interval
函数,大致可以猜测到elt函数做的事情就是上面方案二中case...when...做的事情。
ELT函数简介
ELT()函数是分值函数,功能有点类似很多编程语言中的switch关键字。
语法:
ELT(N,str1,str2,str3,...)
其中N是要判断的数值,如果N=1,则返回str1,如果N=2,则返回str2,以此类推。
总结
本文针对分组统计提出了三种实现方式,各有优劣吧。
针对以上内容有任何疑问或者建议欢迎留言评论~
创作不易,欢迎一键三连~~~