3

私はテーブルを持っています"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

私が受け取る結果は列全体ですが、各学生の平均点数を計算するにはどうすればよいですか?

4

2 に答える 2

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ため、不在の場合は機能します。NULLYpuもそのために使用できますsum
  • class_idは数値タイプであるbigintため、正確には、先行ゼロは単なるノイズです。の代わりに
    使用してください。class_id = 1class_id = 0001
于 2012-05-04T13:21:02.860 に答える
2

「groupby」句が欠落しているように見えます。私は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

乾杯

于 2012-05-04T12:43:31.950 に答える