2014-02-28 81 views
1

客戶要求我爲他們的報表提取一些額外的會計數據。我一直在寫一個可以適應這個問題的查詢時遇到了麻煩。用於在一個查詢中獲取付款和發票的MySQL查詢

什麼他們最初想要的是得到屬於某個帳戶在特定日期範圍內的所有「支付」,訂購的最古老的第一個,這是一個簡單的聲明如下

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的功能我不知道這可以爲我做這個?謝謝。

回答

2

您可以使用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)。

+0

到目前爲止,這工作非常好,謝謝。我相信我的問題是對工會工作方式的誤解。一個新的問題出現了,當我嘗試添加一個**,其中payments.account_id =?**子句後付款p它給了我一個**未知列'payments.customer_id'在'where子句'** SQL錯誤。即使我嘗試使用** p.account_id **而不是** payments.accounts_id **,它仍然無法找到列名稱。我將如何去做這件事? – SixteenStudio

+1

@SixteenStudio。 。 。該查詢使用表別名來提高查詢的可讀性。表別名是表名的縮寫。在第一個子查詢中使用'p.account_id'。否則,只需在兩個子查詢中包含'account_id',並在外部查詢中使用'where account_id =?'。 –

+0

我看到我沒有在子查詢中包含正確的列名。完善! – SixteenStudio