仅对所选行求和

时间:2015-08-01 16:35:04

标签: sql sql-server

以下查询获取客户声明:

SELECT  t.S_Type,t.Number, t.Debit, t.Credit,t.CustID,b.Balance
FROM    Statement as t
    CROSS apply
    (
        SELECT  Balance = SUM(Debit) - SUM(Credit)
        FROM    Statement as x
        WHERE   x.Number<= t.Number 
    ) b

ORDER BY t.Number

查询结果:

type            #    Debit  credit  cid  balance 
Sales Invoice   1   200.00  0.00    3   200.00
Sales Invoice   10  850.00  0.00    3   1050.00
Service Invoice 11  90.00   0.00    21  1140.00
Sales Invoice   12  20.00   0.00    3   1160.00
Sales Invoice   13  200.00  0.00    2   1360.00
Sales Invoice   14  20.00   0.00    9   1380.00
Sales Invoice   15  120.00  0.00    17  1500.00
Sales Invoice   16  100.00  0.00    19  1600.00
Sales Invoice   17  140.00  0.00    20  1740.00
Sales Invoice   18  4250.00 0.00    16  5990.00
Sales Invoice   19  2500.00 0.00    22  8490.00
Sales Invoice   2   100.00  0.00    7   8590.00
Sales Invoice   20  1225.00 0.00    2   9815.00
Sales Invoice   3   200.00  0.00    1   10015.00
Sales Invoice   4   520.00  0.00    2   10535.00
Sales Invoice   5   25.00   0.00    1   10560.00
Sales Invoice   6   160.00  0.00    2   10720.00
Sales Invoice   7   20.00   0.00    7   10740.00
Sales Invoice   9   850.00  0.00    2   11590.00

但是我想获得id为7的客户声明。我使用的查询是:

SELECT  t.S_Type,t.Number, t.Debit, t.Credit,t.CustID,b.Balance
FROM    Statement as t
    CROSS apply
    (
        SELECT  Balance = SUM(Debit) - SUM(Credit)
        FROM    Statement as x
        WHERE   x.Number<= t.Number 
    ) b
where t.CustID='7'
ORDER BY t.Number

此查询的结果是:

type            #   Debit   credit  cid balance
Sales Invoice   2   100.00  0.00    7   8590.00
Sales Invoice   7   20.00   0.00    7   10740.00

然而,结果是错误的。我希望它是:

balance

100.00

120.00

查询有什么问题?

2 个答案:

答案 0 :(得分:5)

要修复您的查询,您需要将CustID添加到相关cross apply,以便仅为外部范围内的客户计算总和,而不是全部:

SELECT  t.S_Type, t.Number, t.Debit, t.Credit, t.CustID, b.Balance
FROM    Statement AS t
CROSS APPLY
    (
        SELECT  Balance = SUM(Debit) - SUM(Credit)
        FROM    Statement AS x
        WHERE   x.Number <= t.Number AND t.CustID = x.CustID
    ) b
WHERE t.CustID='7'
ORDER BY t.Number

如果您使用的是SQL Server 2012+,那么更好的替代也应该更好地使用sum()作为窗口函数:

SELECT 
    S_Type, Number, Debit, Credit, CustId, 
    Balance = SUM(Debit - Credit) OVER (PARTITION BY CustId ORDER BY Number) 
FROM Statement 
WHERE CustID='7'
ORDER BY Number

您的原始查询(没有where子句)将是:

SELECT 
 S_Type, Number, Debit, Credit, CustID,
 Balance = SUM(Debit - Credit) OVER (ORDER BY number) 
FROM Statement 
ORDER BY Number

答案 1 :(得分:3)

CROSS APPLY WHERE中添加以下内容:

AND x.CustID = t.CustID

最后我得到了你需要的东西。为此,您还需要按客户过滤。否则,累计余额将按整套进行,之后您只显示客户7.

更改后,您将只为客户7提供累积余额。

正确的SQL:

SELECT  t.S_Type,t.Number, t.Debit, t.Credit,t.CustID,b.Balance
FROM    Statement as t
    CROSS apply
    (
        SELECT  Balance = SUM(Debit) - SUM(Credit)
        FROM    Statement as x
        WHERE   x.Number<= t.Number and x.CustID = t.CustID
    ) b
where t.CustID='7'
ORDER BY t.Number