一位客户要求我为他们的报表提取一些额外的会计数据。我在编写可以满足此要求的查询时遇到了问题。
他们最初想要的是获取属于某个帐户的某个日期范围内的所有“付款”,从旧到大排序,这是一个简单的语句如下
SELECT * FROM `payments`
WHERE `sales_invoice_id` = ?
ORDER_BY `created_at` ASC;
但是,现在他们希望将新提出的“发票” 作为声明的一部分。我似乎无法为此编写正确的查询。 Union 似乎不起作用,而 JOINS 的行为就像,嗯,加入,所以我无法为每笔付款/发票获得单独的行;相反,它将它们合并在一起。理想情况下,我会按如下方式检索一组结果:
payment.amount | invoice.amount | created_at
-----------------------------------------------------------
NULL | 250.00 | 2014-02-28 8:00:00
120.00 | NULL | 2014-02-28 8:00:00
这样我就可以遍历这些以生成完整的语句。我尝试的最新查询如下:
SELECT * FROM `payments`
LEFT OUTER JOIN `sales_invoices`
ON `payments`.`account_id` = `sales_invoices`.`account_id`
ORDER BY `created_at` ASC;
第一个问题是 "created_at" 列不明确,所以我不确定如何合并它们。第二个问题是它合并行并带回不正确的重复行。
我是不是以错误的方式思考这个问题,或者我不知道 MySQL 是否有一个功能可以为我做这件事?谢谢。
最佳答案
您可以为此使用union all
。您只需要仔细定义列:
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;
您的问题专门针对 MySQL。其他数据库支持一种叫做full outer join
的join类型,也可以使用这种类型的查询(MySQL不支持full outer join
)。
关于用于在一个查询中获取付款和发票的 MySQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22095419/