【Mysql】实现中位数计算

--需求:求一串数据的中位数,若共有偶数个数据则取中间两个数的平均值

create table ta (sc int)

insert into ta values(80),(90),(81),(72),(55),(60);-- 偶数条

mysql> select * from ta order by sc;
+------+
| sc   |
+------+
|   55 |
|   60 |
|   72 |
|   80 |
|   81 |
|   90 |
+------+
6 rows in set (0.00 sec)

-- 基本实现
SELECT avg(t1.sc) as median_val FROM ( 
SELECT @rownum:=@rownum+1 as row_number, d.sc 
FROM ta d, (SELECT @rownum:=0) r 
WHERE 1 
ORDER BY d.sc
) as t1, 
( 
SELECT count(*) as total_rows 
FROM ta d 
WHERE 1  
) as t2 
WHERE 1 
AND t1.row_number in ( floor((total_rows+1)/2), floor((total_rows+2)/2) );
+------------+
| median_val |
+------------+
|    76.0000 |
+------------+
1 row in set (0.03 sec)

-- 增加筛选字段
alter table ta add na varchar(10);

update ta set na='Bai' where mod(sc,2)=0;
update ta set na='Hei' where mod(sc,2)=1;

mysql> select * from ta order by na,sc;
+------+------+
| sc   | na   |
+------+------+
|   60 | Bai  |
|   72 | Bai  |
|   80 | Bai  |
|   90 | Bai  |
|   55 | Hei  |
|   81 | Hei  |
+------+------+
6 rows in set (0.00 sec)

-- 最终实现
SELECT t1.na,
avg(t1.sc) as median_val FROM ( 
SELECT case when @na<>na then @rownum:=1 else @rownum:=@rownum+1 end as row_number, d.sc ,@na:=d.na na
FROM (SELECT @rownum:=0) r ,
(select @na:='' ) n,
ta d
WHERE 1 
ORDER BY d.na,d.sc
) as t1, 
( 
SELECT na,count(*) as total_rows 
FROM ta d 
WHERE 1 
group by na 
) as t2 
WHERE 1 
and t1.na=t2.na
AND t1.row_number in ( floor((total_rows+1)/2), floor((total_rows+2)/2) )
group by t1.na;
+------+------------+
| na   | median_val |
+------+------------+
| Bai  |    76.0000 |
| Hei  |    68.0000 |
+------+------------+
2 rows in set (0.02 sec)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL计算中位数可以使用以下两种方法: 方法一:使用内置函数 MySQL中的内置函数 `SUBSTRING_INDEX()` 可以用于截取字符串,通过将结果按照升序或降序排序,再选择中间的值就可以得到中位数。 示例: ``` SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(column_name,',', ((LENGTH(column_name)-LENGTH(REPLACE(column_name,',',''))+1) DIV 2)),',',-1) AS median_value FROM table_name; ``` 其中 `column_name` 是需要计算中位数的列名, `table_name` 是表名。 方法二:使用自定义函数 如果需要经常计算中位数,可以创建一个自定义函数来实现。以下是一个计算中位数的自定义函数的示例代码: ``` DELIMITER $$ CREATE FUNCTION `get_median`(`values` TEXT) RETURNS DECIMAL(10,2) BEGIN DECLARE median DECIMAL(10,2); DECLARE position INT; SET @row_num = (SELECT COUNT(*) FROM (SELECT CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(values, ',', n.digit+1), ',', -1) AS DECIMAL(10,2)) AS value FROM (SELECT @row := @row + 1 AS digit FROM (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1, (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2, (SELECT @row:=0) r) n WHERE n.digit < LENGTH(values)-LENGTH(REPLACE(values, ',', ''))+1 ORDER BY value) AS x); SET position = @row_num/2 + 1; IF @row_num % 2 = 0 THEN SET median = (SELECT AVG(CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(values, ',', n.digit+1), ',', -1) AS DECIMAL(10,2))) FROM (SELECT @row_num:=@row_num-1) c, (SELECT CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(values, ',', n.digit+1), ',', -1) AS DECIMAL(10,2)) AS value FROM (SELECT @row := @row + 1 AS digit FROM (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1, (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2, (SELECT @row:=0) r) n WHERE n.digit < LENGTH(values)-LENGTH(REPLACE(values, ',', ''))+1 ORDER BY value LIMIT position-1, 2) ; ELSE SET median = (SELECT CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(values, ',', n.digit+1), ',', -1) AS DECIMAL(10,2)) FROM (SELECT @row_num:=@row_num-1) c, (SELECT CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(values, ',', n.digit+1), ',', -1) AS DECIMAL(10,2)) AS value FROM (SELECT @row := @row + 1 AS digit FROM (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1, (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2, (SELECT @row:=0) r) n WHERE n.digit < LENGTH(values)-LENGTH(REPLACE(values, ',', ''))+1 ORDER BY value LIMIT position-1, 1) ; END IF; RETURN median; END$$ DELIMITER ; ``` 使用方法: ``` SELECT get_median(column_name) AS median_value FROM table_name; ``` 其中 `column_name` 是需要计算中位数的列名, `table_name` 是表名。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值