如何计算每个学生的平均分数

时间:2012-05-04 12:29:03

标签: postgresql select union average

我有一张表"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

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

2 个答案:

答案 0 :(得分:3)

看起来像这样:

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]*$'。您只检查字符串中是否有任何数字。
  • 最好使用ISO格式的日期,它与任何区域设置相同:YYYY-MM-DD
  • 缺席的count有效,因为NULL值不计算在内。 Ypu也可以使用sum
  • 由于class_id是数字类型,确切地说bigint,前导零只是噪音。
    使用class_id = 1代替class_id = 0001

答案 1 :(得分: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

欢呼声