【问题标题】:How to calculate average mark for each student如何计算每个学生的平均分
【发布时间】:2012-05-04 12:29:02
【问题描述】:

我有一张桌子"Register"

有列:

  class_id bigint NOT NULL,
  disciple text,
  datelesson date NOT NULL,
  student_id integer NOT NULL,
  note character varying(2)

现在我要计算每个student_id的平均分和缺勤人数

Select * from "Register" as m

Join

(SELECT AVG(average), COUNT(abs) FROM (SELECT
  CASE
      WHEN "note" ~ '[0-9]' THEN CAST("note" AS decimal) 
  END AS average,
  CASE
      WHEN "note" ='a' THEN "note"
  END AS abs
FROM "Register" ) AS average)n 
on class_id=0001 
And datelesson between '01.01.2012' And  '06.06.2012' 
And discipline='music' order by student_id

结果是这样的:

0001;"music";"2012-05-02";101;"6";7.6666666666666667;1
0001;"music";"2012-05-03";101;"a";7.6666666666666667;1
0001;"music";"2012-05-01";101;"10";7.6666666666666667;1
0001;"music";"2012-05-02";102;"7";7.6666666666666667;1
0001;"music";"2012-05-03";102;"";7.6666666666666667;1
0001;"music";"2012-05-01";102;"";7.6666666666666667;1

我收到的结果是针对整个列的,但我如何计算每个学生的平均分?

【问题讨论】:

    标签: postgresql select union average


    【解决方案1】:

    可能是这样的:

    SELECT student_id
         , AVG(CASE WHEN note ~ '^[0-9]*$' THEN note::numeric
                                           ELSE NULL END) AS average
         , COUNT(CASE WHEN note = 'a' THEN 1 ELSE NULL END) AS absent
    FROM   "Register"
    WHERE  class_id = 1 
    AND    datelesson BETWEEN '2012-01-01' AND  '2012-06-06' 
    AND    discipline = 'music'
    GROUP  BY student_id
    ORDER  BY student_id;
    

    我添加了一些改进。

    • 您无需将小写标识符用双引号括起来。
    • 如果您想确定note 中只有 个数字,您的正则表达式必须类似于note ~ '^[0-9]*$'。你所拥有的只是检查字符串中是否有 any 数字。
    • 最好使用 ISO 格式的日期,它适用于任何语言环境:YYYY-MM-DD
    • count 用于缺勤有效,因为 NULL 值不计算在内。 Ypu 也可以使用 sum
    • 由于 class_id 是数字类型,bigint 准确地说,前导零只是噪音。
      使用class_id = 1 而不是class_id = 0001

    【讨论】:

      【解决方案2】:

      在我看来,您缺少“分组依据”子句。我不熟悉 postgress,但我怀疑这个想法同样适用。

      这里是 transact-sql 中的一个例子:

      --create table  register
      --(
      --class_id bigint NOT NULL,
      --  disciple text,
      --  datelesson date NOT NULL,
      --  student_id integer NOT NULL,
      --  grade_report integer not null,
      --  )
      
      
      --drop table register
      
      delete from register
      go
      
      insert into register 
          values( 1, 'math', '1/1/2011', 1, 1)
      insert into register 
          values( 1, 'reading', '1/1/2011', 1, 2)
      insert into register 
          values( 1, 'writing', '1/1/2011', 1, 5)
      
      insert into register 
          values( 1, 'math', '1/1/2011', 2, 8)
      insert into register 
          values( 1, 'reading', '1/1/2011', 2, 9)
      
      SELECT student_id, AVG(grade_report) as 'Average',  COUNT(*) as 'NumClasses'
      from register
      WHERE  class_id=1
      group by student_id
      order by student_id
      

      干杯

      【讨论】:

      • go 不是有效的 PostgreSQL 语句。此外,Postgres 需要 ; 来终止语句。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-02
      • 1970-01-01
      • 2021-07-27
      • 2021-04-21
      • 2016-03-28
      • 1970-01-01
      相关资源
      最近更新 更多