注意:本文均为SQL Server代码,其他数据库可能需要根据对应语法进行修改

创建测试用表:

# 创建学生成绩表:
create table #grade(
id int,
name varchar(10),
score int
)

# 向成绩表中插入数据:
insert into #grade values
(1,'Kevin',85),
(2,'Mary',59),
(3,'Andy',60),
(4,'Tony',79),
(5,'Lucky',90),
(6,'Bob',60),
(7,'Tom',100),
(8,'Lucy',90),
(9,'Cherry',92),
(10,'Ada',99),
(11,'Alice',83),
(12,'Amy',82);

查询一组数据的众数

方法1:
1)首先对数据按照值的不同进行分组,并对每组中的数据进行计数,再根据计数的大小进行降序排序;
2)上述1)中结果集的第一行即要求取的众数所在的行。如果是多个众数则需要输出所有排名计数相等的列

方法一的代码为:

select  top(1) WITH TIES
score,
count(score) as sc_count 
from #grade 
group by score 
order by sc_count desc

--只有一个众数也可以使用:
select top(1) score,count(score) as sc_count from #grade 
group byscore  order by sc_count desc

top(1) WITH TIES会返回所有最高次数的记录。而top(1)只会返回一行记录,如果后续行数的数字有相同的数值也不会返回,故只适用于一个众数的情况。

同时我们也可以使用窗口函数进行排序并筛选

select score
from (
select score,
dense_rank() over(order by number desc) as rnk
from (
select score, count(score) as number
from #grade
group by score
) x
) y
where rnk = 1

方法2:
1)首先对数据按照值的不同进行分组,并对每组中的数据进行计数;
2)使用max函数找出统计个数的最大值及其对应的被统计值,此被统计值就是要求的众数。

具体代码为:

with pro_group as
(select score,count(score) as number from #grade group by score)
select score,number from pro_group where number=(select max(number) from pro_group)

或者使用子查询的方法:

select score,number 
from (select score,count(score) as number from #grade group by score)b
where number=(select max(number) from 
(select score,count(score) as number from #grade group by score)d
)

查询一组数据的中位数

方法一:
核心思想是对于一组要求其中位数的数据,无论数据的总行数是奇数还是偶数,都取这组数据排序后最中间的两个数的平均值作为中位数。当数据的总行数是奇数时,数据经排序后最中间的数取两次以计算平均值。

select avg(score)
from
(
  select score,
  count(*) over() total,
  row_number() over(order by score) rn
  from #grade
) g
where g.rn in (
floor(cast((total+1) as decimal)/2),ceiling(cast((total+1) as decimal)/2)
)

这里使用到两个四舍五入的函数:
CEILING() - 返回最小的整数,使这个整数大于或等于指定数的数值运算。即向上取整
FLOOR() - 返回最大整数,使这个整数小于或等于指定数的数值运算。即向下取整

方法二:
对奇数与偶数的个数分情况处理:

select avg(score)
from (
  select score,
  count(*) over() total,
  cast(count(*) over() as decimal)/2 mid,
  ceiling(cast(count(*)over() as decimal)/2) next,
  row_number() over(order by score) rn
  from #grade
) x
where ( total%2 = 0 and rn in ( mid, mid+1 ))
      or ( total%2 = 1 and rn = next)

对于其他的数据库的写法,可以参考一下这个链接:
https://geek-docs.com/sql/sql-examples/sql-to-calculate-the-median.html