对GROUP BY结果进行分组

时间:2015-12-06 18:57:44

标签: c# sql sql-server group-by subquery

我有一个问题:

Select 
    (coalesce(sum(Ledger.Debit), 0) - coalesce(sum(Ledger.Credit), 0))   
    + Accounts.PreviousBalance  [Balance] 
FROM 
    Accounts
LEFT join 
    Ledger on Accounts.ID = Ledger.AccountId
Where 
    Accounts.Status = 'Active'
GROUP BY 
    Accounts.ID, Accounts.PreviousBalance

并返回23行所有帐户摘要,表明每个帐户有多少客户支付( - ve)和接收(+ ve):

Balance
=========
800655.00
1869213.50
-6365.25
1148160.00
145743.70
804225.00
157625.00
66440.00
972950.00
780063.50
646680.75
277761.00
347100.00
-70882.50
-7435.50
431940.00
1319340.00
245685.00
372400.00
158220.00
608108.00
6777029.00
1147920.00

现在我想要总结一下这个摘要。支付和接收累积值多少钱。 E.g:

Summary
===========
-84683.25      //sum of all negative values
19077259.45    //sum of all positive values

我是这样做的:

SELECT SUM([Balance]) as [Summary]
From 
(
    SELECT CASE WHEN [Balance] > 0 THEN 'Receieve' ELSE 'Pay' END AS 'Type', [Balance]
    From 
    (
        SELECT --Accounts.ID,
            -- ( Debit - Credit ) + Previous balance = balance
        (coalesce(sum(Ledger.Debit), 0) - coalesce(sum(Ledger.Credit), 0))   
        + Accounts.PreviousBalance  [Balance]
        FROM Accounts
        LEFT join Ledger ON Accounts.ID = Ledger.AccountId
        WHERE Accounts.Status = 'Active'
        GROUP BY Accounts.ID, Accounts.PreviousBalance
    ) as accountsSummary
) as summary
GROUP BY [Type]

但我知道这不是好的和优化的方式。这是一些凌乱的嵌套子查询方法。必须有更清洁或更好的方法。如何用更好的方法实现它?

3 个答案:

答案 0 :(得分:2)

放手一搏:

WITH Balances
AS (
    SELECT 
        (coalesce(sum(Ledger.Debit), 0) - coalesce(sum(Ledger.Credit), 0)) + Accounts.PreviousBalance  [Balance] 
    FROM 
        Accounts
    LEFT join 
        Ledger on Accounts.ID = Ledger.AccountId
    Where 
        Accounts.Status = 'Active'
    GROUP BY 
        Accounts.ID, Accounts.PreviousBalance
),
Receipts AS (
    SELECT SUM(Balance) Balance
    FROM Balances
    WHERE Balance > 0
),
Payments AS (
    SELECT SUM(Balance) Balance
    FROM Balances
    WHERE Balance < 0
)    
SELECT Balance FROM Receipts 
UNION 
SELECT Balance FROM Payments

答案 1 :(得分:1)

在外部查询中,只需区分group by中的值和否定值,这就是您所需要的一切

WITH Balances
AS (
    SELECT 
        (coalesce(sum(Ledger.Debit), 0) - coalesce(sum(Ledger.Credit), 0)) + Accounts.PreviousBalance  [Balance] 
    FROM 
        Accounts
    LEFT join 
        Ledger on Accounts.ID = Ledger.AccountId
    Where 
        Accounts.Status = 'Active'
    GROUP BY 
        Accounts.ID, Accounts.PreviousBalance
),
select SUM(Balance)
from Balances
group by case when Balance < 0 then 1 else 0 end

答案 2 :(得分:0)

为什么不使用LINQ。首先使用SQL获取整个数据。然后使用c#(使用LINQ)查询它。这会容易得多。