【问题标题】:How to sum from multiple columns and segregate into separate column if result is positive and negative如果结果是正数和负数,如何从多列中求和并分离到单独的列中
【发布时间】:2020-09-02 07:15:28
【问题描述】:

我正在使用 postgresql,需要编写一个查询来对来自两个不同表的不同列的值求和,然后如果是正数或负数,则将它们分成单独的列。

例如,

下面是源表

下面是需要创建的结果表,在填充时也要使用它

我在下面编写了查询以汇总总和并能够填充 TOT_CREDIT 和 TOT_DEBIT 列。是否有任何优化的查询来实现这一点?

select  t.account_id,
        t.transaction_date,
        SUM(t.transaction_amt) filter (where t.transaction_amt >= 0) as tot_debit,
        SUM(t.transaction_amt) filter (where t.transaction_amt < 0) as tot_credit,
        case
        when
        (
            SUM(t.transaction_amt) + 
            SUM(COALESCE(b.credit_balance,0)) +
            SUM(COALESCE(b.debit_balance,0))
        ) < 0
        then
        (
            SUM(t.transaction_amt) + 
            SUM(COALESCE(b.credit_balance,0)) +
            SUM(COALESCE(b.debit_balance,0))
        )
        end as credit_balance,
        case
        when
        (
            SUM(t.transaction_amt) + 
            SUM(COALESCE(b.credit_balance,0)) +
            SUM(COALESCE(b.debit_balance,0))
        ) > 0
        then
        (
            SUM(t.transaction_amt) + 
            SUM(COALESCE(b.credit_balance,0)) +
            SUM(COALESCE(b.debit_balance,0))
        )
        end as debit_balance,
from 
    transaction t   

LEFT OUTER JOIN balance b ON (t.account_id = b.account_id 
                                        and t.transaction_date = b.transaction_date 
                                        and b.transaction_date=t.transaction_date- INTERVAL '1 DAYS')
group by
    t.account_id,
    t.transaction_date

请指点一下。

编辑 1:此查询未按预期方式工作。

【问题讨论】:

    标签: sql postgresql aggregate-functions


    【解决方案1】:

    一种方法是将您的逻辑分解为小查询并最终加入它们!

    select tw.account_id, tw.t_date,tw.t_c,th.T_D,fo.C_B,fi.d_B from 
    (select account_id, Transaction_date as t_date, sum(Transaction_AMT) as t_C from TransactionTABLE 
    where Transaction_AMT<0 group by  account_id, Transaction_date ) as tw inner join
    (select account_id, Transaction_date as t_date, sum(Transaction_AMT) as t_d from TransactionTABLE 
    where Transaction_AMT>0 group by  account_id, Transaction_date ) as th on tw.account_id=th.account_id and tw.t_date=th.t_date inner join
    (select account_id, Transaction_date as t_date, sum(Transaction_AMT) as C_B from TransactionTABLE 
    where sum(Transaction_AMT)<0 group by  account_id, Transaction_date ) as fo on th.account_id=fo.account_id and th.t_date=fo.t_date inner join
    (select account_id, Transaction_date as t_date, sum(Transaction_AMT) as d_B from TransactionTABLE 
    where sum(Transaction_AMT)>0 group by  account_id, Transaction_date ) as fi on fi.account_id=fo.account_id and fi.t_date=fo.t_date; 
    

    否则

    您可以尝试以下方法来计算 d_B 在 Transaction_date 和 account_id 上的运行计数

    select  account_id,
            transaction_date,
            SUM(transaction_amt) filter (where transaction_amt >= 0) as tot_debit,
            SUM(transaction_amt) filter (where transaction_amt < 0) as tot_credit,
    sum(transaction_amt) over (partition by account_id where sum(transaction_amt)<0) as credit_balance,
    sum(transaction_amt) over (partition by account_id where sum(transaction_amt)>=0) as debit_balance
    from TransactionTABLE group by account_id, Transaction_date order by 1,2;
    

    【讨论】:

    • 我已经编辑了我的问题并提供了有效的查询,只是想知道哪种方式更好
    • 也许,您可以通过测试两个查询的复杂性和执行时间来自行检查,然后您就有答案了!
    • 我的查询未按预期方式工作。有什么方法可以减少您的查询中显示的连接以实现性能优势
    • 您可以使用过度分区方法来计算您的场景中的此类运行计数。我不确定是否,我已经正确使用它们,你为什么不尝试一下?更多信息请访问link
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多