2017-06-02 106 views
3

我有2個表:查詢平均點每個學生

學生:

id  name  
    2  ABC  
    13  DEF  
    22  GHI  

學期:

id  student_id  sem  marks          
    1  2    1  {"math":3, "physic":4, "chemis":5} 
    2  2    2  {"math":2.5, "physic":4.5, "chemis":5} 
    3  2    3  {"math":3, "physic":3.5, "chemis":4} 
    5  13    1  {"math":3, "physic":4, "chemis":5} 
    6  13    2  {"math":3, "physic":4, "chemis":5} 

因此,例如用student_id數據= 2:

平均分數=( (3 + 4 + 5)/ 3)+(2.5 + 4.5 + 5)/ 3 +(3 + 3.5 + 4)/ 3)/3=3.83

有沒有辦法按學生ID查詢平均分數組?

student_id  average  number_of_sems  
    2    3.83  3     
    13    xxx   2   

我試圖通過主題來算:

SELECT 
    t1.student_id, 
    t1.count, 
    (SELECT sum(xx.count) 
    FROM 
    (SELECT (marks:: JSON ->> 'math') :: DOUBLE PRECISION AS count 
     FROM "Semester" 
     WHERE student_id= t1.student_id) AS xx) 
FROM 
    (
    SELECT 
     student_id, 
     count(1) 
    FROM "Semester" 
    GROUP BY student_id 
) AS t1; 

但仍然不知道如何繼續。這可能是不好的解決方案。

回答

2

這包括學生沒有標記:

SELECT st.id, avg(m.value) 
FROM student st 
    LEFT JOIN semester se 
     ON st.id = se.student_id 
    LEFT JOIN LATERAL (SELECT value::numeric 
         FROM jsonb_each_text(se.marks) 
        ) m 
     ON TRUE 
GROUP BY st.id; 

┌────┬────────────────────┐ 
│ id │  avg   │ 
├────┼────────────────────┤ 
│ 2 │ 3.8333333333333333 │ 
│ 13 │ 4.0000000000000000 │ 
│ 22 │     │ 
└────┴────────────────────┘ 
(3 rows) 
+0

謝謝你提醒平均 - 我分數和:) –

2

試試這個:

select student_id 
, avg((marks->>m)::float) average 
, count(distinct sem) number_of_sems 
from semestr s 
join student t on s.student_id = t.id 
left outer join json_object_keys(marks) m on true 
group by student_id; 
student_id |  average  | number_of_sems 
------------+------------------+---------------- 
      2 | 3.83333333333333 |    3 
     13 |    4 |    2 
(3 rows) 

更新

爲pozs說 - 我們也許應該沒有考試還算學期爲semestres ...

+0

這隻會工作,當'marks'不能'NULL'和'{}'(空對象)沒有。 – pozs

+0

是真的。你認爲我應該在沒有任何考試的情況下算一個學期嗎? –

+0

這是在OP上,但他/她沒有指定。但延期學期是學期&它不會傷害'平均()'無論如何(至少它值得注意恕我直言) – pozs

0

感謝所有使用json_each_text()和avg()函數的想法。 所以在情況下,如果目的是在1名學生每個科目獲得平均分:

SELECT 
    st.id, 
    json_data.key AS subject, 
    SUM(json_data.value::DOUBLE PRECISION) AS sum_value, 
    avg(json_data.value::DOUBLE PRECISION) AS avg_value 
FROM student AS st, 
json_each_text(st.marks::JSON) AS json_data 
GROUP BY si.id, subject;