Reputation: 27
I am having some difficulty generating a query that works in the situation I am in. Here are the details...
1 table = billing
1 table = billing dates
billing = basically when an invoice is generated, it creates a row in billing with a primary key, an invoice id, the users id, the users username, their actual name, the invoice date, the invoice total, and the payments made
billing dates = when a payment is made to an invoice, it creates a row in billing dates with a primary key, an id (which is the same as the primary key in billing table), an invoice id (same as the invoice id in billing), the users id (same as users id in billing), the date paid, the amount paid
I am trying to create an ageing report that will pull each outstanding invoice and display it in a 30/60/90/90+ table in PHP to the end user. So if invoice #12 has a $100 balance on it, along with two $10 payments and the invoice is 60 days old, it would show this info in the report. Here is what I have...
$sql17 = "SELECT
$mysql_billing.login_id, $mysql_billing.primary_key, $mysql_billing.a_name,
SUM($mysql_billing.custotal) AS finaltotal,
SUM($mysql_billing_dates.amount) AS paidtotal,
$mysql_billing.custotal - $mysql_billing_dates.amount AS total
FROM $mysql_billing
LEFT JOIN $mysql_billing_dates ON $mysql_billing.login_id = $mysql_billing_dates.login_id
GROUP BY login_id
ORDER BY a_name ASC";
when I run that, some are correct, while most are not. I cannot figure out what the inconsistency is. Any ideas would be greatly appreciated and maybe I am going down the wrong road?
MORE
When I do the following the correct values show...
SELECT
$mysql_billing.login_id, $mysql_billing.primary_key, $mysql_billing.a_name,
SUM($mysql_billing.custotal) AS finaltotal
FROM $mysql_billing
GROUP BY login_id
ORDER BY a_name ASC
but in the original example, it doesnt always pull the correct value?
Upvotes: 2
Views: 535
Reputation: 4031
Okay, I believe I understand what's happening.
So, presumably either table can have more than one record per login_id, which is why you're doing the sum and group by. However, take a look at what your query gives you back when you take out the aggregates and the group by and I think you may understand the problem.
Let's say you have table 1 which has 2 records for login_id xxx1234 and table 2 which has 3 records for that login_id. Then when you left join them, you will get 6 records.
e.g.
table 1:
login, custotal
xxx111, 10
xxx111, 20
table 2:
login, amount
xxx111, 30
xxx111, 40
xxx111, 50
after the join:
login, custotal, amount
xxx111 10, 30
xxx111 10, 40
xxx111 10, 50
xxx111 20, 30
xxx111 20, 40
xxx111 20, 50
So you will be potentially getting several times the amounts you expected in your sums.
What you instead want to do is something like this:
SELECT
billing_totals.login_id, billing_totals.primary_key, billing_totals.a_name,
billing_totals.finaltotal,
billing_dates_totals.paidtotal,
(billing_totals.finaltotal - billing_dates_totals.paidtotal) AS total
FROM
(SELECT $mysql_billing.login_id,
$mysql_billing.primary_key,
$mysql_billing.a_name,
SUM($mysql_billing.custotal) AS finaltotal
FROM $mysql_billing GROUP BY login_id) billing_totals
LEFT JOIN
(SELECT $mysql_billing_dates.login_id,
SUM($mysql_billing_dates.amount) AS paidtotal
FROM $mysql_billing_dates GROUP BY login_id) billing_dates_totals
ON (billing_totals.login_id = billing_dates_totals.login_id)
ORDER BY a_name ASC";
Probably need to tweak that slightly as I don't have a mysql to test it on at the moment.
Upvotes: 1
Reputation: 4933
$sql17 = "SELECT $mysql_billing.login_id, $mysql_billing.primary_key, $mysql_billing.a_name, SUM($mysql_billing.custotal) AS finaltotal, SUM($mysql_billing_dates.amount) AS paidtotal, SUM($mysql_billing.custotal) - SUM($mysql_billing_dates.amount) AS total FROM $mysql_billing LEFT JOIN $mysql_billing_dates ON $mysql_billing.login_id = $mysql_billing_dates.login_id GROUP BY login_id ORDER BY a_name ASC";
EDIT : I tried some thing like this for u.
SELECT a.id, (select sum(custotal) from `billing` where id=a.id) as total1,(select sum(amount)
from `billing_dates`
where id=a.id) as total1 from `billing` a
Upvotes: 0