简体   繁体   中英

Partial Pivoting in PostgreSQL or Rails

Assume I have 3 tables, and I can't change any DDL

Class
id: integer
name: string

and

Student
id: integer
name: string
class_id: integer //Foreign key to Class table

and

Score
id: integer
student_id: integer //Foreign key to Student table
subject: string //String enum of "Math", "Physics", "Chemistry"
score: float

Also, assume that the string enum will always correct, filled by only one of those three possible values.

And I need a resulting query like this student_id | student_name | class_name | math | physics | chemistry student_id | student_name | class_name | math | physics | chemistry student_id | student_name | class_name | math | physics | chemistry where math field is the average score of "Math" subject, physics field is the average score of "Physics" subject, and chemistry field is the average score of "Chemistry" subject of the student with id student_id.

I know that I can handle it in Rails ActiveRecord::Base , but even using include, I end up with using many queries.

How can I generate that needed output with using only one query?

You can do this with joins and aggregation:

select s.student_id, s.student_name, c.class_name,
       avg(case when sc.subject = 'Math' then sc.score end) as Math,
       avg(case when sc.subject = 'Physics' then sc.score end) as Physics,
       avg(case when sc.subject = 'Chemistry' then sc.score end) as Chemistry
from students s join
     scores sc 
     on sc.student_id = s.id join
     classes c
     on sc.class_id = cl.id
group by s.student_id, s.student_name, c.class_name;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM