use*_*760 1 postgresql aggregate sum
我有一个学生表和一个不同科目的分数表。我想将所有科目的每个学生的 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),
);
Run Code Online (Sandbox Code Playgroud)
连接 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
Run Code Online (Sandbox Code Playgroud)
如果我添加bonus
到这个查询 ie sum(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
Run Code Online (Sandbox Code Playgroud)
您可以使用子查询,但不需要。只是不要求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 ;
Run Code Online (Sandbox Code Playgroud)
在较新版本的 Postgres 中,您只能通过以下方式使用student
组中表的主键:
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 ;
Run Code Online (Sandbox Code Playgroud)
如果你想要一个子查询,这是一种方法:
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 ;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1985 次 |
最近记录: |