首发于 SQL实战

计算百分位数的三种方法

百分位数:如果将一组数据从小到大排序,并计算相应的累计百分位,则某一百分位所对应数据的值就称为这一百分位的百分位数。可表示为:一组n个观测值按数值大小排列。如,处于p%位置的值称第p百分位数。

下面给出3种计算方式:

1. PERCENT_RANK() OVER(ORDER BY .....)

返回某列或某列组合后每行的百分比排序,返回值在0~1之间,使用此函数可以直接得出百分位数

2. RANK() OVER(ORDER BY .....)

使用rank()函数可以统计出当前行的排名,配合总数即可算出百分位数,总数使用COUNT(1) OVER() 即可得出

3. COUNT(1) OVER(ORDER BY ..... RANGE BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)

手动调整窗口范围,确认当前行的排名,配合总数即可算出百分位数,总数使用COUNT(1) OVER() 即可得出

下面将举例给出具体使用方法

举例场景:计算学生成绩的百分位数

注:本次测试在oracle环境下完成,不过使用到的函数绝大部分数据库都支持,大家有兴趣的话可以尝试一下其他数据库

创建学生成绩表:

写入测试数据:

INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('张三','政治',90.5);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('李四','政治',79.0);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('王五','政治',85.5);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('赵六','政治',93.0);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('小明','政治',92.5);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('小红','政治',88.0);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('小吕','政治',76.5);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('小高','政治',93.0);

INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('张三','外语',87.0);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('李四','外语',92.0);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('王五','外语',69.5);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('赵六','外语',76.0);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('小高','外语',76.0);

INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('张三','高数',95.0);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('李四','高数',70.5);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('王五','高数',65.0);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('赵六','高数',88.5);

INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('张三','算法',59.5);

INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('张三','数据结构',99.5);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('李四','数据结构',89.0);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('王五','数据结构',69.5);
INSERT INTO TEST.STUDENT_SCORE (name,course,score) VALUES ('赵六','数据结构',90.5);

1.使用 PERCENT_RANK() OVER(ORDER BY .....) 计算各个科目的百分位数:

结果:



2.使用 RANK() OVER(ORDER BY .....) 计算各个科目的百分位数:

结果(排名从0开始):



3.使用COUNT(1) OVER(ORDER BY ..... RANGE BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) 计算各个科目的百分位数:

结果(排名从0开始):



扩展知识:

ROWS、RANGE的区别:

ROWS是以行来划分窗口范围

RANGE会以实际值来划分窗口范围

举例:

结果:



由上述结果就可以看出,取下一行时:

ROWS关键字是按照ORDER BY的排序取的下一行到最后一行

RANGE关键字会跳过相同的值,从下一个值开始取,类似于rank排序的算法

注:计算百分位数时,相同值的百分位数也一样,所以第三种方式使用RANGE关键字实现

两个鬼故事纯外卖店加盟徐大堡核电站男孩起名黄子用锦起名字大全营口热线网上起姓名准不准psv神秘海域宝宝起名免费软件版单人套餐起名字小加工厂起名大全参照带水字的公司起名字兰州交大研究生被杀小孩起什么名字女孩八字起名打分天津卫视节目预告工薪族理财笔画8笔画的字有起名宝宝宝宝起名宝典建筑公司起名大全两字电脑怎么设置密码js6899带鸟字的诗句属鼠之人起名字宜忌一起名字河北联通网上营业厅辛弃疾诗词孙姓起名孙姓男宝宝起名大全电子政务外网猪qq头像林姓男孩起名字少年生前被连续抽血16次?多部门介入两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”淀粉肠小王子日销售额涨超10倍高中生被打伤下体休学 邯郸通报单亲妈妈陷入热恋 14岁儿子报警何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言张家界的山上“长”满了韩国人?男孩8年未见母亲被告知被遗忘中国拥有亿元资产的家庭达13.3万户19岁小伙救下5人后溺亡 多方发声315晚会后胖东来又人满为患了张立群任西安交通大学校长“重生之我在北大当嫡校长”男子被猫抓伤后确诊“猫抓病”测试车高速逃费 小米:已补缴周杰伦一审败诉网易网友洛杉矶偶遇贾玲今日春分倪萍分享减重40斤方法七年后宇文玥被薅头发捞上岸许家印被限制高消费萧美琴窜访捷克 外交部回应联合利华开始重组专访95后高颜值猪保姆胖东来员工每周单休无小长假男子被流浪猫绊倒 投喂者赔24万小米汽车超级工厂正式揭幕黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发当地回应沈阳致3死车祸车主疑毒驾恒大被罚41.75亿到底怎么缴妈妈回应孩子在校撞护栏坠楼外国人感慨凌晨的中国很安全杨倩无缘巴黎奥运校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变王树国卸任西安交大校长 师生送别手机成瘾是影响睡眠质量重要因素国产伟哥去年销售近13亿阿根廷将发行1万与2万面值的纸币兔狲“狲大娘”因病死亡遭遇山火的松茸之乡“开封王婆”爆火:促成四五十对奥巴马现身唐宁街 黑色着装引猜测考生莫言也上北大硕士复试名单了德国打算提及普京时仅用姓名天水麻辣烫把捣辣椒大爷累坏了

两个鬼故事 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化