16

如果我想将当前行减去上一行,我应该查询什么。我将在 vb6 中循环使用它。像这样的东西:

Row
1
2
3
4
5

在第一个循环值 1 不会被扣除,因为它没有前一行,这没关系。下一个循环值 2 将被前一行的值 1 减去。依此类推,直到最后一行。

我怎样才能实现这个程序?通过 SQL 查询或 VB6 代码。任何都可以。

4

2 回答 2

31

假设你有一个排序列——比如说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 表本质上是无序的,因此没有指定排序的列就没有“前一行”之类的东西。

于 2013-07-10T01:16:13.430 回答
0

使用光标:

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;
于 2018-01-09T17:50:43.563 回答