如果我想将当前行减去上一行,我应该查询什么。我将在 vb6 中循环使用它。像这样的东西:
Row
1
2
3
4
5
在第一个循环值 1 不会被扣除,因为它没有前一行,这没关系。下一个循环值 2 将被前一行的值 1 减去。依此类推,直到最后一行。
我怎样才能实现这个程序?通过 SQL 查询或 VB6 代码。任何都可以。
如果我想将当前行减去上一行,我应该查询什么。我将在 vb6 中循环使用它。像这样的东西:
Row
1
2
3
4
5
在第一个循环值 1 不会被扣除,因为它没有前一行,这没关系。下一个循环值 2 将被前一行的值 1 减去。依此类推,直到最后一行。
我怎样才能实现这个程序?通过 SQL 查询或 VB6 代码。任何都可以。
假设你有一个排序列——比如说id
——那么你可以在 SQL Server 2012 中执行以下操作:
select col,
col - coalesce(lag(col) over (order by id), 0) as diff
from t;
在 SQL Server 的早期版本中,您可以使用相关子查询执行几乎相同的操作:
select col,
col - isnull((select top 1 col
from t t2
where t2.id < t.id
order by id desc
), 0)
from t
之所以使用isnull()
,是coalesce()
因为 SQL Server 中的一个“错误”在使用coalesce()
.
你也可以这样做row_number()
:
with cte as (
select col, row_number() over (order by id) as seqnum
from t
)
select t.col, t.col - coalesce(tprev.col, 0) as diff
from cte t left outer join
cte tprev
on t.seqnum = tprev.seqnum + 1;
所有这些都假设您有一些用于指定排序的列。它可能是一个id
, 或一个创建日期或其他东西。SQL 表本质上是无序的,因此没有指定排序的列就没有“前一行”之类的东西。
使用光标:
CREATE TABLE t (id int)
INSERT INTO t
VALUES(1)
INSERT INTO t
VALUES(2)
INSERT INTO t
VALUES(3)
INSERT INTO t
VALUES(4)
DECLARE @actual int;
DECLARE @last int;
DECLARE @sub int;
SET @last = 0;
DECLARE sub_cursor CURSOR FOR
SELECT *
FROM t OPEN sub_cursor
FETCH NEXT
FROM sub_cursor INTO @actual;
WHILE @@FETCH_STATUS = 0 BEGIN
SELECT @sub = @actual - @last print cast(@actual AS nvarchar) + '-' + cast(@last AS nvarchar) + '=' + cast(@sub AS nvarchar)
SET @last = @actual
FETCH NEXT FROM sub_cursor INTO @actual;
END
DROP TABLE t
CLOSE sub_cursor; DEALLOCATE sub_cursor;