Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查询每个学生的平均分_Sql_Json_Postgresql - Fatal编程技术网

Sql 查询每个学生的平均分

Sql 查询每个学生的平均分,sql,json,postgresql,Sql,Json,Postgresql,我有两张桌子: 学生: id name 2 ABC 13 DEF 22 GHI 学期: id student_id sem marks 1 2 1 {"math":3, "physic":4, "chemi

我有两张桌子:

学生:

   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}   
例如,当学生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;
但仍然不知道如何继续。这可能是个糟糕的解决方案

试试这个:

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所说,我们可能应该将没有考试的学期计算为学期…

这包括没有分数的学生:

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)

感谢大家提出使用json_每个_text()和avg()函数的想法。 因此,如果目的是让一名学生在每门学科中获得平均分数:

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;

感谢您提醒avg-I除以总和除以计数:)这只适用于
标记
不能为
NULL
,也不能为
{}
(空对象)的情况。这在OP上,但他/她没有指定。但是推迟的学期是学期&不管怎样,它都不会损害
avg()
(至少值得注意)