To solve your problem, I did the following (all of the code below is available on the fiddle here):
CREATE TABLE _order
(
order_id INT NOT NULL PRIMARY KEY,
total_price INT NOT NULL
);
populate:
INSERT INTO _order VALUES
(1, 1000), (2, 2000), (3, 3000);
I used _order
for the table name instead of orders
because I don't like plural table names - a table is a set and should have a singular name. It may contain 0, 1 or many records - not necessarily many. I also use snake_case for table names. These are just a personal things - choose a convention and stick to it!
Then:
CREATE TABLE payment
(
order_id INT NOT NULL,
amount INT NOT NULL,
CONSTRAINT payment_order_id_fk FOREIGN KEY (order_id) REFERENCES _order (order_id)
);
and:
INSERT INTO payment VALUES
(1, 500), (2, 2000), (3, 1000), (3, 500), (3, 750);
and run the following SQL:
SELECT
o.order_id, o.total_price, t.order_id, t.sum_pay, o.total_price - t.sum_pay AS owed
FROM
_order o
JOIN
(
SELECT
order_id, SUM(amount) AS sum_pay
FROM
payment
GROUP BY order_id
) AS t
ON o.order_id = t.order_id
ORDER BY o.order_id;
Result:
order_id total_price order_id sum_pay owed
1 1000 1 500 500
2 2000 2 2000 0
3 3000 3 2250 750
I left the extra fields in there so that you can see what's going on. We can clean this up as follows to give your desired result:
SELECT
o.order_id AS o_id, o.total_price - t.sum_pay AS owed
FROM
_order o
JOIN
(
SELECT
order_id, SUM(amount) AS sum_pay
FROM
payment
GROUP BY order_id
) AS t
ON o.order_id = t.order_id
WHERE o.total_price - t.sum_pay != 0
ORDER BY o.order_id;
Result:
o_id owed
1 500
3 750
and to get the overall sum of what's owed for every order, we do the following:
SELECT
SUM(owed) AS total_owed_all_orders
FROM
(
SELECT
o.order_id AS o_id, o.total_price - t.sum_pay AS owed
FROM
_order o
JOIN
(
SELECT
order_id, SUM(amount) AS sum_pay
FROM
payment
GROUP BY order_id
) AS t
ON o.order_id = t.order_id
WHERE o.total_price - t.sum_pay != 0
) AS t2;
Result:
total_owed_all_orders
1250
Et voilà - results as requested.
You might also want to try something like the following if you wish to avoid too many subselects - and you get all of your desired data in one go, so to speak.
SELECT
o.order_id AS o_id, o.total_price - t.sum_pay AS owed, SUM(o.total_price - t.sum_pay) OVER () AS tot_owed
FROM
_order o
JOIN
(
SELECT
order_id, SUM(amount) AS sum_pay
FROM
payment
GROUP BY order_id
) AS t
ON o.order_id = t.order_id
WHERE o.total_price - t.sum_pay != 0
ORDER BY o.order_id;
Result:
o_id owed tot_owed
1 500 1250
3 750 1250
Window functions are well worth getting to know as they are very powerful and will repay any effort spent learning them many times over! The best presentation I've ever seen about them is this by Bruce Momjian (a PostgreSQL core team member) - it's about PostgreSQL, but the same basics will apply. Other presentations by him available here.