2016-02-05 97 views
0

我想在兩個相關的表中獲得amount列的總和。在兩個不同的相關表中獲得兩個字段的總和

發票表:

----------------------------------------- 
| id | student_id | created | updated | 
----------------------------------------- 
| 5 |  25  | date | date | 
----------------------------------------- 

發票項目表:

------------------------------ 
| id | invoice_id | amount | 
------------------------------ 
| 1 |  5  | 250 | 
------------------------------ 
| 2 |  5  | 100 | 
------------------------------ 
| 3 |  5  | 40  | 
------------------------------ 

付款表:

------------------------------ 
| id | invoice_id | amount | 
------------------------------ 
| 1 |  5  | 100 | 
------------------------------ 
| 2 |  5  | 290 | 
------------------------------ 

所需的輸出:

-------------------------------------- 
| id | invoiceTotal | paymentTotal | 
-------------------------------------- 
| 1 |  390  | 390  | 
-------------------------------------- 

我已經試過

SELECT 
    i.id, 
    sum(ii.amount) as invoiceTotal, 
    sum(p.amount) as paymentTotal 
FROM 
    invoices i 
LEFT JOIN 
    invoice_items ii ON i.id = ii.invoice_id 
LEFT JOIN 
    payments p ON i.id = p.invoice_id 
WHERE 
    i.student_id = '25' 
GROUP BY 
    i.id 

什麼這似乎做的是正確計算支付的總和,但invoice_items.amount似乎已經由6重複查詢(這是payments的編號)。

我已閱讀過SO herehere上的類似問題,但這些例子比我想要做的要複雜得多,我無法弄清楚要放在哪裏。

+0

@Stidgeon好吧,我更新了問題。 – Joseph

回答

0

連接會導致笛卡爾產品出現問題。如果學生有多個發票項目和付款,那麼總數將是錯誤的。

一種方法最適合所有發票是union all/group by方法:

select i.id, sum(invoiceTotal) as invoiceTotal, sum(paymentTotal) as paymentTotal 
from ((select i.id, 0 as invoiceTotal, 0 as paymentTotal 
     from invoices i 
    ) union all 
     (select ii.invoiceId, sum(ii.amount) as invoiceTotal, NULL 
     from invoiceitems ii 
     group by ii.invoiceId 
    ) union all 
     (select p.invoiceId, 0, sum(p.amount) as paymentTotal 
     from payments p 
     group by p.invoiceId 
    ) 
    ) iip 
group by id; 

對於一個學生,我會建議相關子查詢:

select i.id, 
     (select sum(ii.amount) 
     from invoiceitems ii 
     where ii.invoiceid = i.id 
     ) as totalAmount, 
     (select sum(p.amount) 
     from payment p 
     where p.invoiceid = i.id 
     ) as paymentAmount 
from invoices i 
where i.studentid = 25; 
+0

謝謝。第二個例子正是我想要做的。 – Joseph

相關問題