user1710960
user1710960

Reputation: 27

mysql query on 2 tables with sum

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

Answers (2)

FoolishSeth
FoolishSeth

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

DevT
DevT

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

Related Questions