【问题标题】:MySQL Query for getting Payments & Invoices in one queryMySQL 查询用于在一个查询中获取付款和发票
【发布时间】:2014-04-01 11:17:25
【问题描述】:

一位客户要求我为他们的报表提取一些额外的会计数据。我在编写一个可以容纳这个的查询时遇到了麻烦。

他们最初想要的是从某个日期范围内获得属于某个帐户的所有“付款”,从最旧的开始排序,这是一个简单的声明,如下所示

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

但是,现在他们希望将新提出的 “发票” 作为声明的一部分。我似乎无法为此编写正确的查询。联合似乎不起作用,并且 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 是否有一个我不知道的功能可以为我做到这一点?谢谢。

【问题讨论】:

    标签: mysql sql database join union


    【解决方案1】:

    您可以为此使用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 的连接类型,也可以用于这种类型的查询(MySQL 不支持full outer join)。

    【讨论】:

    • 到目前为止,这非常有效,谢谢。我相信我的问题是对工会如何运作的误解。出现了一个新问题,当我尝试在付款 p 之后添加一个 where payment.account_id = ? 子句时,它会在“where子句”中给我一个 Unknown column 'payments.customer_id' b> SQL 错误。即使我尝试使用 p.account_id 而不是 payments.accounts_id 它仍然找不到列名。我该怎么办?
    • @SixteenStudio 。 . .该查询使用表别名来使查询更具可读性。表别名是表名的缩写。在第一个子查询中使用 p.account_id。否则,只需在两个子查询中包含account_id,并在外部查询中使用where account_id = ?
    • 我看到我没有在子查询中包含正确的列名。完美!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多