Question

A customer has asked me to pull some extra accounting data for their statements. I have been having trouble writing a query that can accomodate this.

What they initially wanted was to get all "payments" from a certain date range that belongs to a certain account, ordered as oldest first, which was a simple statement as follows

SELECT * FROM `payments` 
WHERE `sales_invoice_id` = ? 
ORDER_BY `created_at` ASC;

However, now they want to have newly raised "invoices" as part of the statement. I cannot seem to write the correct query for this. Union does not seem to work, and JOINS behave like, well, joins, so that I cannot get a seperate row for each payment/invoice; it instead merges them together. Ideally, I would retrieve a set of results as follows:

payment.amount | invoice.amount | created_at
-----------------------------------------------------------
NULL           | 250.00         | 2014-02-28 8:00:00
120.00         | NULL           | 2014-02-28 8:00:00

This way I can loop through these to generate a full statement. The latest query I tried was the following:

SELECT * FROM `payments` 
LEFT OUTER JOIN `sales_invoices` 
ON `payments`.`account_id` = `sales_invoices`.`account_id` 
ORDER BY `created_at` ASC;

The first problem would be that the "created_at" column is ambiguous, so I am not sure how to merge these. The second problem is that it merges rows and brings back duplicate rows which is incorrect.

Am I thinking about this the wrong way or is there a feature of MySQL I am not aware of that can do this for me? Thanks.

Was it helpful?

Solution

You can use union all for this. You just need to define the columns carefully:

select ip.*
from ((select p.invoice_id, p.amount as payment, NULL as invoice, p.created_at
       from payments p
      ) union all
      (select i.invoice_id, NULL, i.amount, i.created_at
       from sales_invoices i
      )
     ) ip
order by created_at asc;

Your question is specifically about MySQL. Other databases support a type of join called the full outer join, which can also be used for this type of query (MySQL does not support full outer join).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top