SQL 求平均值时去掉极值

时间:2022-07-24
本文章向大家介绍SQL 求平均值时去掉极值,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在一些比赛中,为了公平起见,算法端会在评委给出的分数里面去掉一个最高分和一个最低分,再求平均分,平均分即是选手的最后得分。

在某次比赛中,评委给选手 A 打出了一组分数:98、88、94、92、95、93、92,我们怎么用 SQL 来计算选手 A 的最后得分呢?

假设评委打出的分数存储在 t 表的 score 字段里面。

方案一

找到最高分和最低分,将最高分和最低分从分数组中剔除。

使用 max()min() 函数可以分别找到最高分和最低分。

具体的 SQL 实现如下:

SELECT
  AVG(score) AS final_score
FROM
  t
WHERE score NOT IN (
    (SELECT
      MIN(score)
    FROM
      t),
    (SELECT
      MAX(score)
    FROM
      t)
  )

上面的 SQL 还存在一点问题,当最高分或者最低分的分值存在多个时,使用这个方法计算出来的最后得分是不对的。

方案二

先对所有的分数求和,再减去最高分和最低分,最后求平均值。

SELECT 
  (SUM(score) - MIN(score) - MAX(score)) / 
  (COUNT(*) - 2) AS final_score 
FROM
  t

即使存在重复的最高分或最得分,用这个方法计算出来的最后得分也是正确的。

方案三

如果数据库支持窗口函数,可以用窗口函数对分值分别按升序和降序排序(分值相同的序号也不同),去掉序号为 1 的记录再求平均值。

SELECT
  AVG(score) AS final_score
FROM
  (SELECT
    score,
    row_number () over (
  ORDER BY score) score_asc_rn,
  row_number () over (
  ORDER BY score DESC) score_desc_rn
  FROM
    t) t
WHERE score_asc_rn > 1
  AND score_desc_rn > 1

封面图片由 Юрий Сидоренко 在 Pixabay 上发布。