Postgres / SQL:针对付款来源的建模费用和退款

时间:2013-04-16 04:59:10

标签: sql postgresql join

我有以下模型,我想写一个将返回未花费的学分的查询。积分有许多费用,反过来有很多退款。到目前为止,我对查询的尝试如下,但我发现它有问题,需要一些帮助。所有amount列均为正数。

Credit
id (integer)
amount (decimal)

Charge
id (integer)
credit_id (integer)
amount (decimal)

Refund
id (integer)
charge_id (integer)
amount (decimal)

我的查询如下:

SELECT credits.*,
"credits"."amount" - coalesce(sum("charges"."amount"), 0) + coalesce(sum("refunds"."amount"), 0) AS unspent_amount 
FROM "credits"
LEFT OUTER JOIN "charges" ON "charges"."credit_id" = "credits"."id"
LEFT OUTER JOIN "refunds" ON "refunds"."charge_id" = "charges"."id"
GROUP BY "credits"."id"
HAVING "credits"."amount" > coalesce(sum("charges"."amount"), 0) - coalesce(sum("refunds"."amount"), 0) LIMIT 1

我遇到的问题是,如果收费有很多退款,则收费金额的总和将为N *,其中N是退款的数量。我想每次充电ID只计算一次充电金额。

最终我想要credit.amount> charge_against_credits.amount - refunds_for_those_charges.amount。我怎样才能做到这一点?

编辑:

以下是一些可以重现问题的示例记录:

credits
id 1
amount 25.0

charges
id 1
credit_id 1
amount 25.0

refunds
id 1
charge_id 1
amount 20.0
-----------
id 2
charge_id 1
amount 5.0

编辑2:

预期产出:

credits:
1 row:
id: 1, amount: 25.0, unspent_amount: 25.0

1 个答案:

答案 0 :(得分:1)

SELECT  a.ID,
        (a.amount - COALESCE(b.totalCharges, 0)) + COALESCE(c.totalRefunds, 0) AS unspent_amount
FROM    credits AS a
        LEFT JOIN
        (
            SELECT  credit_ID, SUM(amount) totalCharges
            FROM    charges
            GROUP   BY credit_ID
        ) AS b  ON a.ID = b.credit_ID
        LEFT JOIN
        (
            SELECT  aa.credit_ID, SUM(bb.amount) totalRefunds
            FROM    charges AS aa
                    LEFT JOIN Refund AS bb
                        ON  aa.ID = bb.Charge_ID
            GROUP   BY aa.credit_ID
        ) AS c  ON b.credit_ID = c.credit_ID
--  WHERE   clause ...here....