-
2021-12-08 14:17:20
在项目开发报表的时候遇到了一个问题,需要统计表中,数据的平均值和中位数。
mysql给的函数中,有求平均值的函数AVG,但是没有求中位数的函数。从网上搜了一些,感觉比较复杂,这个时候咱们可以用一个巧妙的骚操作来解决。
中位数就是一组数据中间的那个值,这个时候咱们可以先排序数据,排序以后,中间的那个值就是中位数了。
当数据总量是奇数的时候,中间的就是中位数,比如有 5个数据,则排序以后第三个就是中位数。当数据总量是偶数的时候,这个时候咱们规定,取中间靠下的那个记录为中位数。比如当总记录数是6个的时候咱们取第3个数据,总记录数是8的时候咱们去第4个数据。实际上这里也可以改动一下,取出来中间的两个数据,都当做中位数,或者求两个的平均值当中位数。
下面是sql,大家可以根据自己的表设计稍作改动。
总体思路就是先根据某一个数值列去排序${orderColumn},然后查出来行号,和总记录数。这个查询当做子查询,在外侧在套一层查询,查询行号,是总记录数一半的那条记录。当总记录数是奇数的时候count/2是个小数,所以这里用了一个向上取整的函数。
select * from ( select (@rownum := @rownum + 1) rownum, c.num, s.* from zkx_safety_assess_value s, (select @rownum := 0) r, (SELECT COUNT(1) num from zkx_safety_assess_value where type = #{type} ) c where s.type = #{type} order by ${orderColumn} ) tab where tab.rownum = CEILING(tab.num/2)
更多相关内容 -
MySQL取中位数
2021-11-18 10:05:40位数为单的时候,排序结果相减为0即为中位数。 位数为双的时候,排序结果相减为1,-1的值求均值即为中位数 select user_id,avg(record_seconds) from (select user_id, record_seconds, # 求差值 cast(a ...思路:将数据正向、反向排序,序号相减。
|1|2|3|4|5|
|5|4|3|2|1||1|2|3|4|5|6|
|6|5|4|3|2|1|以上面的数为例,
位数为单的时候,排序结果相减为0即为中位数。
位数为双的时候,排序结果相减为1,-1的值求均值即为中位数select user_id,avg(record_seconds) from (select user_id, record_seconds, # 求差值 cast(a as signed)-cast(a as signed) as diff from (select user_id, record_seconds, # 升序 row_number() over(partition by user_id order by record_seconds)a, # 降序 row_number() over(partition by user_id order by record_seconds)b from tb1)p1 )p2 # 差值为-1,0,1 则求均值(位数为单只有0,位数为双则有1,-1) where diff in(-1,0,1) group by user_id;
-
mysql 求中位数、四分位数
2021-01-19 02:32:10当记录是偶数时,中位数是中间两个数的平均 SELECT GROUP_CONCAT( id ), avg( `VALUE` ) FROM (#第二层开始 SELECT id, @INDEX := @INDEX + 1 AS myindex, `VALUE` -- myindex代表的是这一列数,@index是位置 FROM ...CREATE TABLE `student_t` (
`id` varchar(32) NOT NULL,
`value` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into student_t (id,`value`)
values ('A',40),
('B',50),
('C',60),
('D',70),
('E',80),
('F',90);
第一步先给表加一个列,列里面是对分数的排序(即标明了位置)
SELECT
id,
@INDEX := @INDEX + 1 AS myindex,
`VALUE` -- myindex代表的是这一列数,@index是位置
FROM
student_t
INNER JOIN ( SELECT @INDEX := 0 ) AS initvar ON 1 = 1
ORDER BY
`VALUE` #最内层
当记录是奇数时,中位数中间位置的数;当记录是偶数时,中位数是中间两个数的平均
SELECT
GROUP_CONCAT( id ),
avg( `VALUE` )
FROM
(#第二层开始
SELECT
id,
@INDEX := @INDEX + 1 AS myindex,
`VALUE` -- myindex代表的是这一列数,@index是位置
FROM
student_t
INNER JOIN ( SELECT @INDEX := 0 ) AS initvar ON 1 = 1
ORDER BY
`VALUE` #最内层
) AS t
WHERE
myindex = floor( @INDEX / 2+1 ) OR myindex = ceil( @INDEX / 2 )
四分位数
SELECT
GROUP_CONCAT( id ),
avg( `VALUE` )
FROM
(#第二层开始
SELECT
id,
@INDEX := @INDEX + 1 AS myindex,
`VALUE` -- myindex代表的是这一列数,@index是位置
FROM
student_t
INNER JOIN ( SELECT @INDEX := 0 ) AS initvar ON 1 = 1
ORDER BY
`VALUE` #最内层
) AS t
WHERE
myindex = floor(( @INDEX+1) /4 )
SELECT
GROUP_CONCAT( id ),
avg( `VALUE` )
FROM
(#第二层开始
SELECT
id,
@INDEX := @INDEX + 1 AS myindex,
`VALUE` -- myindex代表的是这一列数,@index是位置
FROM
student_t
INNER JOIN ( SELECT @INDEX := 0 ) AS initvar ON 1 = 1
ORDER BY
`VALUE` #最内层
) AS t
WHERE
myindex = floor(3*( @INDEX+1) /4 )
扫码关注更多的分享内容,祝好呀~~
-
【转】MySQL如何计算中位数
2021-01-19 03:17:18而MYSQL没有直接提供median()这样的直接算中位数的算法。于是就在百度上百度了下。看到有为朋友提供了一种算法。但是只要代码,没有解释。花了挺久的时间,终于理解了这种算法的含义。源代码如下:create table ...前2天,老板有个报表需求,需要用到中位数算法。而MYSQL没有直接提供median()这样的直接算中位数的算法。于是就在百度上百度了下。看到有为朋友提供了一种算法。但是只要代码,没有解释。花了挺久的时间,终于理解了这种算法的含义。
源代码如下:
create table state_mid
as
select user_id,avg(price)
from (
select e.user_id, e.price
from
producte e, producte d
where e.user_id = d.user_id
group by e.user_id, e.price
having sum(case when e.price = d.price then 1 else 0 end)>=
abs(sum(sign(e.price - d.price)))
)t
group by user_id。
首先,向写出这位代码的前辈致敬。
这段代码的精髓地方,就在于
having sum(case
when e.price = d.price then 1 else 0 end)>= abs(sum(sign(e.price -
d.price)))
理解这段代码,其实就是理解了中位数的一个体征:
1、当一列数列的数量N是奇数的时候。则中位数的那个数字在数列中的数量>=中位数减去所有数字的结果的符号值(1,0,-1中的一个)的和的绝对值。
简单的例子:
例:数列为1,2,3,4,5
可以看出它的中位数为3,它的数量是1.所以 having
sum(case when e.price = d.price then 1
else 0 end)=1。
而它减去所以数字的差值为2,1,0,-1,-2.符号值就为1,1,0,-1,-1.符号值的和为1+1+0+(-1)+
(-1)=0.所以绝对值也为0.所以abs(sum(sign(e.price
- d.price)))=0
因此 having
sum(case when e.price = d.price then 1 else 0 end)>= abs(sum(sign(e.price
- d.price)))成立。
接下来我们看下如果是2的话,会不会条件成立。首先2的数量是1,它与所有数字的差值为
1,0,-1,-2,-3,符号值为1,0,-1,-1,-1。和为-2,绝对值就为2.可以看出,这就和我们要求的
条件不符合,就会被剔除。
其他种数列的话大家也可以试试,这里举一个最简单的例子用于方便理解
2、当一列数列的数量N是偶数的时候。这时候用条件筛选出来的就会是最靠近中位数的那两个数字。则为最靠近中位数的那两个数字在数列中的数量>=那两个数字减去所有数字的结果的符号值(1,0,-1中的一个)的和的绝对值。ps:我们都知道,当数列数量N为偶数的时候,中位数就是用最靠近中位数的那两个数字求平均值得来的。
所以 select
user_id,avg(price)
from
producte e, producte d
where e.user_id = d.user_id
group by e.user_id, e.price
having sum(case when e.price = d.price then 1 else 0 end)>=
abs(sum(sign(e.price - d.price)))
就是帮我们找出了最中间的那一个数字(N为奇数的时候)或者两个数字(N为偶数的时候)。
最后在求出这一个数字或者两个数字的平均值,就是我们所要求的中位数了。
-
如何使用简单的SQL查询在MySQL中计算中位数
2021-01-19 00:53:54什么是中位数?数值型数组的中位数是在数据排序后位于数组中间项的值。如果数组有偶数个元素,中位数就是最中间的两个数值的平均数。中位数对于了解“我的值是否位于中间?”非常有用。比如,我在学校的最后一次考试... -
SQLServer下取中位数(中位值)的方法
2021-02-08 15:00:10从中位数的定义可知,所研究的数据中有一半小于中位数,一半大于中位数。中位数的作用与算术平均数相近,也是作为所研究数据的代表值。在一个等差数列或一个正态分布数列中,中位数就等于算术平均数... -
mysql:求中位数
2019-02-22 14:32:55先从内部的一个子查询开始 —— 为 @rowindex 赋值的子查询会为每个成绩赋予一个自增后的序号,并对 grades 排序 [译者注...然后,外层查询的 SELECT 子句返回上述两个值的平均值作为中位数。 -----------------... -
MySQL一条语句算出中位数
2018-09-12 22:00:29因为数据量太大,没法一一修正,想到用中位数来代替,但mysql没有现成的中位数函数,琢磨半天想到的,记录出来分享一下。 这个方法也可以用来算四分位数等 复习一下什么是中位数: 一串数字,按从小到... -
mysql_如何用mysql计算每组的中位数
2018-01-19 21:19:10有一天,我不得不计算MySQL中每个组的中位数。 事实证明这并不像听起来那么简单,主要是因为在MySQL中不存在median()函数。 经过一些反复试验和一些有用的提示,我想到了。 尤其对于那些不熟悉MySQL的人来说,这里... -
mysql查询中位数(窗口函数的使用)
2021-03-24 23:04:55mysql查询中位数(leetcode569的延伸) Create table If Not Exists Employee (Id int, Company varchar(255), Salary int) Truncate table Employee insert into Employee (Id, Company, Salary) values ('1', 'A',... -
Mysql分组求中位数
2020-11-05 11:49:17– Mysql分组中位数例子:求每组年龄中位数 – 建表语句 CREATE TABLE es( id INT, name VARCHAR(50), age INT, group INT ) – 插入数据 INSERT INTO es VALUES(1,‘Tom’,23,1); INSERT INTO es VALUES(2,‘Kio’,... -
分组求中位数
2014-09-04 16:27:38分组求中位数 select c.age,avg(r.AMOUNT) as AMOUNT from (select a.age ,a.AMOUNT,(select count(1) from testzhongweishu where age=a.age and (AMOUNT)) as Num from testzhong。 -
MySQL获取分组数据中每组的中位数
2020-08-16 17:34:48 from中的思考:需要拿到可能多个的表中那些必须的数据(考虑需不需要子查询,子查询需不需要添加统计结果的列),将这些数据在整合成一个表。 where where中的思考:拿到表中的全部数据了,然后开始挑选符合... -
SQL笔面试题:如何求取中位数?
2021-08-19 00:32:34公众号后台回复“图书“,了解更多号主新书内容 作者:胖里 来源: 胖里的日常 先来看看中位数的概念。中位数(Median)又称中值,统计学中的专有名词,是按顺序排... -
mysql使用GROUP BY分组实现取前N条记录的方法
2020-09-10 02:16:01主要介绍了mysql使用GROUP BY分组实现取前N条记录的方法,结合实例形式较为详细的分析了mysql中GROUP BY分组的相关使用技巧,需要的朋友可以参考下 -
MySQL 截取小数位数
2021-01-19 05:30:40查询出来的结果为:,每隔3位用逗号进行截取,返回的结果为String类型的,如果MyBatis中接收的字段不是String类型的,转换结果会出错。2)SELECT ROUND(1478568.2457, 2) 四舍五入法;查询结果为... -
mysql-控制小数位数
2020-12-30 07:47:59这里有个值得注意的地方是,d可以是负数,这时是指定小数点左边的d位整数位为0,同时小数位均为0;SELECT ROUND(100.3465,2),ROUND(100,2),ROUND(0.6,2),ROUND(114.6,-1);结果分别:100.35,100,0.6,1102、T... -
mysql小数位数设置
2021-01-19 14:26:08Mysql中设置小数点用什么数据类型 decimalmysql中小数点用decimal(x,y)进行存储, 示例如下,创建测试表,create table test_decimal(id int, fee_value decimal(20,3));插入测试数据, insert into test_decimal ... -
MySQL查询小数点位数
2021-01-19 15:16:14怎么查询某个字段中小数有几位?MySQL数据库:通过下面sql就可以查出来,有2位col*100,有3位col*1000,一次类推;select * from ws_inventory_item where real_quantity*1000 - floor(real_quantity*1000) > 0... -
Mysql 生成固定位数的随机数
2021-01-18 22:30:41项目中需要动态随机生成一些固定位数的随机数,如8位,5位等。之前看到的写法是这样ROUND(ROUND(RAND(),5)*100000)这样写不太准确,有几率出现4位的情况,Rand() 函数是取 0 ~ 1(无限接近) 的随机函数如果 某此... -
MySQL生成固定位数的随机数
2021-01-18 21:47:16项目中需要动态随机生成一些固定位数的随机数,如8位,5位等。之前看到的写法是这样ROUND(ROUND(RAND(),5)*100000)这样写不太准确,有几率出现4位的情况,Rand() 函数是取 0 ~ 1(无限接近) 的随机函... -
mysql 中位数
2016-06-04 13:02:20mysql中位数 奇数去中间的,偶数取中间两个数的平均值SELECT avg(t1.money) as median_val FROM ( SELECT @rownum:=@rownum+1 as row_number, d.money FROM core_order d, (SELECT @rownum:=0) r WHERE 1 – ... -
mySQL求中位数、众数
2020-01-13 18:13:28mysql 取中位数、众数 -- 求众数 SELECT score, count(score) from scores GROUP BY score HAVING count(score) >= (SELECT max(a.b) from (SELECT count(score) as b from scores GROUP BY score) a ) -- ... -
MySQL查询一组数据的众数和中位数
2019-03-05 14:00:412)上述1)中结果集的第一行即要求取的众数所在的行。 方法2:适用于一组数据有一个或多个众数的情况 1)首先对数据按照值的不同进行分组,并对每组中的数据进行计数; 2)使用max函数找出统计个数的... -
如何使用简单的 SQL 查询在 MySQL 中计算中位数
2017-09-29 09:26:20什么是中位数? 数值型数组的中位数是在数据排序后位于数组中间项的值。如果数组有偶数个元素,中位数就是最中间的两个数值的平均数。 中位数对于了解“我的值是否位于中间?”非常有用。比如,我在学校的最后... -
如何获取位于MySQL小数点前2位的数字?
2021-01-25 18:23:01为了使数字位于小数点前2位,可以使用div的概念。让我们创建一个表-mysql>...借助insert命令将一些记录插入表中-mysql>insertintodemo1values(456.54);mysql>insertintodemo1values(50.64);m... -
【Mysql】实现中位数计算
2016-09-29 16:27:05--需求:求一串数据的中位数,若共有偶数个数据则取中间两个数的平均值create table ta (sc int)insert into ta values(80),(90),(81),(72),(55),(60);-- 偶数条select * from ta order by na,sc-- 基本实现 SELECT ... -
mysql生成指定位数的随机数及批量生成随机数的方法
2021-02-04 16:42:121. 先介绍几个常用的 MySQL 函数RAND() 随机生成 0~1 之间的小数(0<1) CEILING 向上取整FLOOR 向下取整 2. 生成随机数 -- 生成 3 位的随机数SELECT CEILING(RAND()*900+100);-- 生成 4 位的随机数SELECT CEILING...