代码之家  ›  专栏  ›  技术社区  ›  Finbarr

Postgres/SQL:针对支付源建模收费和退款

  •  0
  • Finbarr  · 技术社区  · 11 年前

    我有以下模型,我想写一个查询,返回未使用的信用。信用卡有很多费用,而这些费用又有很多退款。到目前为止,我的查询尝试如下,但我发现了一个问题,需要一些帮助。所有的 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计算一次收费金额。

    最终,我想要credits.amount>费用总额_against_credits.amount-refrends_for_these_charges.mamount。我如何实现这一点?

    编辑:

    以下是一些将重现问题的样本记录:

    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 回复  |  直到 11 年前
        1
  •  1
  •   John Woo    11 年前
    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....