繁体   English   中英

获取具有多个连接的多列总和时如何防止重复

[英]How to prevent duplicates when getting sum of multiple columns with multiple joins

假设我有 3 个表:发票、费用和付款。 发票可以有多项费用,费用可以有多次付款。

做一个简单的连接,数据看起来像这样:

invoiceid  |   chargeid   |  charge   |  payment
----------------------------------
1          |      1       |    50     |   50
2          |      2       |    100    |   25
2          |      2       |    100    |   75
2          |      3       |    30     |   10
2          |      3       |    30     |   5

如果我加入总和,

select invoiceid, sum(charge), sum(payment)
from invoices i 
inner join charges c on i.invoiceid = c.invoiceid
inner join payments p on p.chargeid = c.chargeid
group by invoiceid

付款总和是正确的,但费用会重复:

invoiceid  |    charges   |   payments
--------------------------------------
1          |     50       |     50
2          |     260      |     115

我想要一个查询来获取发票列表,其中包含每张发票的付款总和和费用总和,如下所示:

invoiceid  |    charges   |   payments
--------------------------------------
1          |     50       |     50
2          |     130      |     115

有没有办法通过修改上面的查询而不使用子查询来做到这一点,因为在处理大量数据时子查询可能会非常慢? 我觉得必须有一种方法可以只在总和中包含独特的费用。

一种方法是在连接分组值之前通过表进行聚合

SELECT i.invoiceid, SumOfCharge, SumOfInvoice
FROM  invoices i 
INNER JOIN  (SELECT InvoiceID, suM(charges) sumOfCharges 
            FROM charges c 
            GROUP BY Invoiceid) c
   on i.invoiceid = c.invoiceid
INNER JOIN (SELECT invoiceid, sum(payment) as SumOfPayment
            FROM charages c
            INNER JOIN payments p on p.chargeid = c.chargeid
            GROUP BY Invoiceid) P
   on i.invoiceID = p.invoiceid

另一种方法是使用相关性对每张发票进行内联

SELECT i.invoiceid
     , (SELECT SUM(charge) FROM charges c WHERE c.invoiceid = i.invoiceid) SumOfCharge
     , SUM(Payment) SumOfInvoice
FROM  invoices i 
INNER JOIN  charges c 
   on i.invoiceid = c.invoiceid
INNER JOIN payments p 
   on p.chargeid = c.chargeid
GROUP BY Invoiceid

您还可以通过使用 LATERAL JOINS 来实现此目的

   SELECT
     i.invoiceid,
     chgs.total_charges,
     pays.total_payments
   FROM
     invoices AS i
     JOIN LATERAL (
        SELECT
            SUM( charge ) AS total_charges
        FROM
            charges AS c
        WHERE
            c.invoiceid = i.invoiceid
     ) AS chgs ON TRUE
     JOIN LATERAL (
        SELECT
            SUM( payment ) AS total_payments
        FROM
            payments AS p
        WHERE
            p.chargeid = c.chargeid
     ) AS pays ON TRUE

我希望这将有所帮助。

select invoiceid, sum(distinct charge)as charges, sum(payment)as payments from yourtable group by invoiceid;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM