java 一组数据中偏差较大的数据_在 MySQL 中,如何计算一组数据的中位数

daecfca094687eccb26dabf86ad3be41.png

php中文网最新课程

每日17点准时技术干货分享

97297d87689e8794d03751fe3479f2b3.png

0baea53b246a94cb4fd0072b632f1936.gif

要得到一组数据的中位数(例如某个地区或某家公司的收入中位数),我们一般要将这一任务细分为 3 个小任务:

1.将数据排序,并给每一行数据给出其在所有数据中的排名;

2.找出中位数的排名数字;

3.找出中间排名对应的值;

下面以某公司员工月收入为例,示例 MySQL 的一些复杂语句的使用。

方法一

创建测试表

首先创建一个收入表,建表语句为:

CREATE TABLE IF NOT EXISTS `employee` (  `id`     INT                  AUTO_INCREMENT PRIMARY KEY,  `name`   VARCHAR(10) NOT NULL DEFAULT '',  `income` INT         NOT NULL DEFAULT '0')  ENGINE = InnoDB  DEFAULT CHARSET = utf8;INSERT INTO `employee` (`name`, `income`)VALUES ('麻子', 20000);INSERT INTO `employee` (`name`, `income`)VALUES ('李四', 12000);INSERT INTO `employee` (`name`, `income`)VALUES ('张三', 10000);INSERT INTO `employee` (`name`, `income`)VALUES ('王二', 16000);INSERT INTO `employee` (`name`, `income`)VALUES ('土豪', 40000);

完成任务 1

将数据排序,并给每一行数据给出其在所有数据中的排名:

SELECT t1.name, t1.income, COUNT(*) AS rankFROM employee AS t1,     employee AS t2WHERE t1.income < t2.income   OR (t1.income = t2.income AND t1.name <= t2.name)GROUP BY t1.name, t1.incomeORDER BY rank;

查询结果为:

2ef291d2976cb9f7bb82e191e3db308e.png

完成小任务 2

找出中位数的排名数字:

SELECT (COUNT(*) + 1) DIV 2 as rankFROM employee;

查询结果为:

f244343ce0dfd41fe835f753f7a31382.png

完成小任务 3

SELECT income AS medianFROM (SELECT t1.name, t1.income, COUNT(*) AS rank      FROM employee AS t1,           employee AS t2      WHERE t1.income < t2.income         OR (t1.income = t2.income AND t1.name <= t2.name)      GROUP BY t1.name, t1.income      ORDER BY rank) t3WHERE rank = (SELECT (COUNT(*) + 1) DIV 2 FROM employee)

查询结果为:

5725dda0896882a3e8330dba7fc5091d.png

至此,我们就找到了如何从一组数据中获得中位数的方法。

方法二

下面,来介绍另外一种优化排名语句的方法。

我们都知道如何给一组数据做排序操作,在本例中,实现方法如下:

SELECT name, incomeFROM employeeORDER BY income DESC

查询结果为:

fbf615e670875df9a299c81113510284.png

那我们可不可以更进一步,对查询出的结果加一列,这一列的数据为排名呢?

我们可以通过 3 个自定义变量的方法来实现这一目标:

第一个变量用来记录当前行数据的收入

第二个变量用来记录上一行数据的收入

第三个变量用来记录当前行数据的排名

SET @curr_income := 0;SET @prev_income := 0;SET @rank := 0;SELECT `name`,       @curr_income := income                                      AS income,       @rank := if(@prev_income != @curr_income, @rank + 1, @rank) AS rank,       @prev_income := @curr_income                                AS dummyFROM employeeORDER BY income DESC

查询结果如下:

178f4bdc5bf5e97329fcfb0b6e2a5790.png

然后再找出中位数的排名数字,进一步找出收入的中位数:

SET @curr_income := 0;SET @prev_income := 0;SET @rank := 0;SELECT income AS medianFROM (SELECT `name`,             @curr_income := income                                      AS income,             @rank := if(@prev_income != @curr_income, @rank + 1, @rank) AS rank,             @prev_income := @curr_income                                AS dummy      FROM employee      ORDER BY income DESC) AS t1WHERE t1.rank = (SELECT (COUNT(*) + 1) DIV 2 FROM employee)

查询结果为:

de1804c9989f9a4b698d70079e575d99.png

至此,我们找了两种方法来解决中位数的问题。撒花。

-END-

声明:本文选自「 php中文网 」,搜索「 phpcnnew 」即可关注!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值