【问题标题】:Count number of students above and below the average score in SQL统计 SQL 中高于和低于平均分的学生人数
【发布时间】:2020-07-16 14:22:04
【问题描述】:

我在下面有一个示例表,我试图让学生人数高于平均分和低于平均分的学生人数。

name    subject classroom   classarm    session     first_term_score    first_term_grade
std1    math    nursery 1A  nursery1    2018/2019     90                 A
std2    eng     nursery 1A  nursery1    2018/2019     70                 A
std3    sci     nursery 1A  nursery1    2018/2019     60                 B
std1    eng     nursery 1A  nursery1    2018/2019     64                 B
std2    math    nursery 1A  nursery1    2018/2019     70                 A

目标结果表应该是这样的

subject   avg_score count_above   count_below
math         80      1                1
eng          65.5    2                0

我已经能够编写一个查询来获取高于平均分数的学生姓名,并且可以轻松地对其进行编辑以获取低于平均分数的学生人数。

SELECT name 
    FROM (SELECT name,
                 AVG(first_term_score) AS average_result
          FROM seveig
          GROUP BY name) sa, 
         (SELECT (AVG(first_term_score)) tavg
          FROM seveig) ta
     WHERE sa.average_result > ta.tavg

这里的问题是我想在一个表格中添加计数,表明高于和低于平均分数的学生数量。

如果一个数字等于平均分,则可以认为它高于平均分。

【问题讨论】:

    标签: mysql sql group-by count window-functions


    【解决方案1】:

    如果你运行的是 MySQL 8.0,你可以使用窗口函数和聚合:

    select
        subject,
        avg_score,
        sum(first_term_score >= avg_score) count_above,
        sum(first_term_score <  avg_score) count_below
    from (
        select t.*, avg(first_term_score) over(partition by subject) avg_score
        from mytable t
    ) t
    group by subject, avg_score
    

    在早期版本中,您可以将表格与计算每个主题的平均分数的聚合查询结合起来:

    select
        t.subject,
        a.avg_score,
        sum(t.first_term_score >= a.avg_score) count_above,
        sum(t.first_term_score <  a.avg_score) count_below
    from mytable t
    inner join (
        select subject, avg(first_term_score) avg_score
        from mytable
        group by subject
    ) a on a.subject = t.subject
    group by t.subject, a.avg_score
    

    编辑:您似乎在运行 Big Query,而不是最初标记的 MySQL。你可以使用COUNTIF():

    select
        subject,
        avg_score,
        countif(first_term_score >= avg_score) count_above,
        countif(first_term_score <  avg_score) count_below
    from (
        select t.*, avg(first_term_score) over(partition by subject) avg_score
        from mytable t
    ) t
    group by subject, avg_score
    

    【讨论】:

    • 你怎么知道它是 BigQuery 而不是 mySQL?看起来 OP 之前的问题也是针对 mySQL 的
    • @MikhailBerlyant:实际上这在我的答案中的 cmets 中进行了讨论(后来被删除)-我提供的第一个查询是引发 BQ 错误消息,并且 OP 确认这就是他们正在运行的。然后我提供了一个 BQ 解决方案,他们接受了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-26
    • 2019-06-30
    相关资源
    最近更新 更多