使用下排的计算字段。比如Running Total

时间:2016-06-16 06:28:23

标签: sql-server calculated-columns running-total

我有一个具有以下结构的表:

1)RowNo

2)BillValue

3)余额

4)X =(我的计算字段)

表格的填写版本如下所示:

RowNo  BillValue  Balance  X
1                 9689454  9689454
2      812,500    8876954  8876954
3      741,343    8135611  8135611
4      838,430    7297181  7297181
5      1,297,151  6000030  6000030
6      1,425,398  6648632  4574632
7      1,022,478  5626154  3552154
8      587,560    5038594  2964594
9      674,655    4363939  2289939
10     355,005    4008934  1934934
11     1,113,673  2895261  821261
12     759,961    2135300  61300
13     61,300     1271654  0 

第一个“X”值=平衡(我称之为X1,这意味着用RowNo提交的x = 1)

X2 = X1 – BillValue

X3 = X2 – BillValue

最后:X(n) = X(n-1) – BillValue

问题提醒我Run Total。但是,它是不同的。 请考虑通过单独加入表格,并使用如下的一些查询:

FROM 
    C1
LEFT JOIN
    C1 C2 ON C1.RowNo = C2.RowNo + 1

我们正在计算第一步中的所有x是错误的。计算后X必须移到下排。

在SQL Server 2012及更高版本中不使用游标的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

编辑1:根据评论添加了StdID

编辑2:修改后的脚本始终使用Balance的第一个值而不是MAX

这可以使用以下脚本完成,无需任何连接:

CREATE TABLE #Order(
    StdID INT,
    RowNo INT IDENTITY(1,1),
    BillValue NUMERIC(10,2),
    Balance NUMERIC(10,2)
);

INSERT INTO #Order(StdID,BillValue,Balance)
VALUES
(1,0,1000),
(1,500,1200),
(1,100,900),
(1,200,700),
(1,100,600),
(2,0,2000),
(2,1000,1200),
(2,500,2500),
(2,400,700),
(2,100,600)

SELECT  StdID,
        RowNo,
        BillValue,
        Balance,
        (FIRST_VALUE(Balance) OVER (PARTITION BY STDID ORDER BY RowNo)-SUM(BillValue) OVER(PARTITION BY STDID ORDER BY RowNo)) AS X
FROM #Order;

DROP TABLE #Order;

答案 1 :(得分:0)

您可以使用以下查询:

SELECT t1.RowNo, t1.BillValue, t1.Balance,
       t2.Balance - SUM(t1.BillValue) OVER (ORDER BY RowNo) AS X
FROM mytable AS t1
CROSS JOIN (SELECT Balance FROM mytable WHERE RowNo = 1) AS t2

使用CROSS JOIN操作来获取初始行的Balance值。使用此值,我们可以通过减去字段X运行总计来计算字段BillValue。可以使用带有SUM子句的函数ORDER BY的窗口版本轻松计算运行总计。此版本的SUM可从SQL Server 2012开始提供。

答案 2 :(得分:0)

您可以创建表格:

CREATE TABLE [dbo].[Bills](
    RowNo int IDENTITY(1,1) NOT NULL,
    BillValue int NOT NULL,
    Balance int NOT NULL
) 

然后创建视图

CREATE VIEW dbo.BillsX
AS
WITH cte AS (
    SELECT *, Balance as X, 1 as lev
    FROM dbo.Bills
    WHERE RowNo = 1
    UNION ALL
    SELECT b.*, (LAG(c.X,0,0) OVER (ORDER BY lev))- b.BillValue, lev+1 
    FROM cte c
    INNER JOIN dbo.Bills b
        ON b.RowNo = c.RowNo +1
)

SELECT  RowNo,
        BillValue,
        Balance,
        X
FROM cte