You could use a subquery but you don't need to. Just don't sum the bonus
and add it in the GROUP BY
list.
Notice that you have to also add the student.id
, even in your original query, in case you have 2 students with same name.
You probably also need coalesce()
for students without any scores:
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 ;
In newer versions of Postgres, you could use only the primary key of the student
table in the group by:
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 ;
If you want a subquery, this is one way:
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 ;
This may not be the best way to do this but it will work.
SELECT c.ClientNo, c.ClientId, c.FullName, i.InvoiceTotalDue, i.InvoiceTotalBalance, r.ReturnChequeTotalDue, r.ReturnChequeTotalBalance, (i.InvoiceTotalBalance + r.ReturnChequeTotalBalance) AS TotalBalance
FROM Client_TBL c
LEFT JOIN (
SELECT ClientNo, SUM(TotalDue) AS InvoiceTotalDue, SUM(TotalBalance) AS InvoiceTotalBalance
FROM Invoice_TBL
GROUP BY ClientNo
) AS i ON c.ClientNo = i.ClientNo
LEFT JOIN (
SELECT ClientNo, SUM(TotalDue) AS ReturnChequeTotalDue, SUM(TotalBalance) AS ReturnChequeTotalBalance
FROM ReturnCheque_TBL
GROUP BY ClientNo
) AS r ON c.ClientNo = r.ClientNo
And of course you could change the subqueries into CTEs. But basically you are going to collect the data pre join since otherwise you are probably going to get bad data (Client 2 for example will have Invoice info that is twice as large and ReturnCheque that is 3 times as large.)
Best Answer
Probably easiest to do with sub-selects:
If least is not availible in your DBMS something like:
should do
A slightly different approach is to use
LATERAL
. I think this is calledCROSS APPLY
insql-server
. I cannot verify this at the moment so you will probably have to modify this: