Sql server 如何减去sql中的前一行?

Sql server 如何减去sql中的前一行?,sql-server,vb6,Sql Server,Vb6,如果要将当前行减去上一行,我应该查询什么。我将在vb6中的循环中使用它。 大概是这样的: Row 1 2 3 4 5 在第一个循环中,值1不会被扣除,因为它没有上一行,这是正常的。 下一个循环值2将被上一行值1减去。依此类推,直到最后一排 我怎样才能做到这一点? 通过SQL查询或VB6代码。任何都可以。假设您有一个排序列,比如说id,那么您可以在SQL Server 2012中执行以下操作: select col, col - coalesce(lag(col) over (or

如果要将当前行减去上一行,我应该查询什么。我将在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
所有这些都假设您有一些列用于指定排序。它可能是一个
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;

请记住,SQL结果集中没有“上一行”这样的内容,除非使用“ORDERBY”子句来定义顺序。另外,你应该试着用关系数据库的集合来思考,所以我希望有人能给你一个集合方面的答案(我现在必须离开)…是的。但是我如何在order by子句中定义它呢?谢谢…提纲(抱歉,我必须运行):定义一个CTE,它使用order by来选择一个顺序,然后使用它添加一个列来定义顺序。然后将CTE连接到x.ROWNUM=y.ROWNUM+1上的自身,并包括x.value-y.value。如果他没有排序列怎么办?行数?在滞后函数中使用COALESCE而不是'default'参数有什么特别的原因吗?@Volodya。习惯
lag()
lead()
接受几个参数。我可以很容易地记住前两个——列和偏移量。创建了一个表
cte
,但它下面的参考是表
t
。修复?@fortune\u p。哎呀。谢谢你的反馈。
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;