Postgresql
PostgreSQL:避免多次對相同的值求和
我有一張學生表和一張不同科目的分數表。我想對所有科目的每個學生的 score1 和 score2 求和,然後為每個學生添加獎金。
CREATE TABLE student ( id serial PRIMARY KEY, name text NOT NULL, bonus integer NOT NULL, ); CREATE TABLE score ( id serial PRIMARY KEY, subject text NOT NULL, score1 integer NOT NULL, score2 integer NOT NULL, student_id integer NOT NULL, CONSTRAINT s_id FOREIGN KEY (student_id) REFERENCES student (id), );
加入 score1 & score2 的查詢如下所示:
SELECT st.name, sum(sc.score1 + sc.score2) as total FROM student st LEFT JOIN score sc ON sc.student_id = st.id group by st.name
如果我添加
bonus
到這個查詢 iesum(sc.score1 + sc.score2 + st.bonus)
,它會為每個學生重複多次(取決於 student_id 在分數表中出現的次數)。我是否必須使用子查詢,即先計算 score1 和 score2 的總和,然後將其添加到獎金中(見下文),還是有更好的方法?
SELECT sq.name, sum(sq.bonus+sq.total) FROM ( SELECT st.bonus, st.name, sum(sc.score1 + sc.score2) as total FROM student st LEFT JOIN score sc ON sc.student_id = st.id group by st.name ) AS sq
您可以使用子查詢,但您不需要。只是不要總結
bonus
並將其添加到GROUP BY
列表中。請注意
student.id
,即使在原始查詢中,您也必須添加 ,以防您有 2 個同名的學生。您可能還需要
coalesce()
沒有任何分數的學生:SELECT st.name, coalesce(sum(sc.score1),0) + coalesce(sum(sc.score2),0) + st.bonus AS total FROM student st LEFT JOIN score sc ON sc.student_id = st.id GROUP BY st.id, st.name, st.bonus ;
student
在較新版本的 Postgres 中,您可以通過以下方式僅使用組中表的主鍵:SELECT st.name, coalesce(sum(sc.score1),0) + coalesce(sum(sc.score2),0) + st.bonus AS total FROM student st LEFT JOIN score sc ON sc.student_id = st.id GROUP BY st.id ;
如果你想要一個子查詢,這是一種方法:
SELECT st.name, coalesce(sc.score, 0) + st.bonus AS total FROM student st LEFT JOIN ( SELECT student_id, sum(score1) + sum(score2) AS score FROM score GROUP BY student_id ) AS sc ON sc.student_id = st.id ;