Reputation: 1
I am developing a website for a charity where amounts are pledged by individuals and recorded into a table. The individuals belong to a group. The payments received are recorded in another table however they are tagged to a group leader and not an individual. There can be multiple payments to reach the pledged amount. I wanted an SQL query that would compare the amounts pledged by a group with the payments tagged to the group leader. My Tables are as follows:
Donor Table
id | group_leader_id | name |
---|---|---|
1001 | 1001 | John |
1002 | 1001 | Steve |
1003 | 1001 | Richard |
1004 | 1004 | Paul |
1005 | 1004 | Stacy |
1006 | 1004 | Lucy |
Pledged Table
id | amount | year |
---|---|---|
1001 | 20 | 2023 |
1002 | 25 | 2023 |
1003 | 10 | 2023 |
1004 | 15 | 2023 |
1005 | 40 | 2023 |
1006 | 50 | 2023 |
Payment Table
id | amount | year |
---|---|---|
1001 | 10 | 2023 |
1001 | 10 | 2023 |
1001 | 20 | 2023 |
1001 | 15 | 2023 |
1004 | 35 | 2023 |
1004 | 35 | 2023 |
1004 | 35 | 2023 |
I have created two queries with sum but how can i compare them to check if the amount that has been pledged has been paid?
query1
SELECT Donor.Name Donor.id , SUM(Pledged.amount)
FROM Donor , Pledged
WHERE Donor.id = Pledged.id
AND year = '2023'
GROUP BY group_leader_id
query2
SELECT Donor.id , SUM(Payment.amount)
FROM Payment
WHERE year = '2023'
GROUP BY Donor.id
Upvotes: 0
Views: 158
Reputation: 3429
with
t as (
select
d.group_leader_id as gid,
max(case
when d.id = d.group_leader_id then d.name
end) as leader,
sum(p.amount) as pledged
from donor as d
left join pledged as p
on p.id = d.id
group by d.group_leader_id
)
select
t.*,
sum(p.amount) as paid
from t
left join payment as p
on p.id = t.gid
group by
t.gid, t.leader, t.pledged;
Result:
+------+--------+----------+----------+
| gid | leader | pledged | paid |
+------+--------+----------+----------+
| 1001 | John | 55.0000 | 55.0000 |
| 1004 | Paul | 105.0000 | 105.0000 |
+------+--------+----------+----------+
Upvotes: 0
Reputation: 86706
With this structure you can't assign a payment to an individual pledge.
This means that your aggregate output would presumably be the amount Pledged per group leader, vs the amount Paid per group leader.
That I need to presume that is one reason you've gotten such poor engagement for your question. Please ensure you include the expected results in your questions, as per the [mre] help page.
WITH
pledge (
donor_id,
donor_name,
year,
pledge_amount
)
AS
(
SELECT
d.group_leader_id,
MAX(CASE WHEN d.id = d.group_leader_id THEN d.Name END),
p.year,
SUM(p.amount)
FROM
donor AS d
INNER JOIN
pledged AS p
ON d.id = p.id
GROUP BY
d.group_leader_id,
p.year
),
payment (
donor_id,
year,
payment_amount
)
AS
(
SELECT
p.id,
p.year,
SUM(p.amount)
FROM
payment AS p
GROUP BY
p.id,
p.year
)
SELECT
pledge.*,
COALESCE(payment.payment_amount, 0)
FROM
pledge
LEFT OUTER JOIN
payment
ON pledge.donor_id = payment.donor_id
AND pledge.year = payment.year
WHERE
pledge.year = 2023
Upvotes: 0
Reputation: 14899
You can JOIN the two queries like this:
SELECT query1.group_leader_id,
Pledged,
Payment,
Pledged - Payment as Difference
FROM (
-- query1 (corrected)
SELECT group_leader_id , SUM(Pledged.amount) as Pledged
FROM Donor
INNER JOIN Pledged ON Donor.id = Pledged.id
WHERE year = '2023'
GROUP BY group_leader_id
) query1
INNER JOIN (
-- query2 (corrected)
SELECT id , SUM(Payment.amount) as Payment
FROM Payment
WHERE year = '2023'
GROUP BY id
) query2 ON query1.group_leadeR_id = query2.id
see: DBFIDDLE
You might need to change some small things, but that's because no desired output was given in your question .... 😢
Upvotes: 1