How can I subtract a previous row in sql?

后端 未结 2 1467
轮回少年
轮回少年 2020-12-09 18:27

What should I query if I wanted to subtract the current row to the previous row. I will use it on looping in vb6. Something Like this:

Row
1
2
3
4
5
<         


        
相关标签:
2条回答
  • 2020-12-09 19:00

    Using Cursor:

    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;
    
    0 讨论(0)
  • 2020-12-09 19:09

    Assuming you have an ordering column -- say id -- then you can do the following in SQL Server 2012:

    select col,
           col - coalesce(lag(col) over (order by id), 0) as diff
    from t;
    

    In earlier versions of SQL Server, you can do almost the same thing using a correlated subquery:

    select col,
           col - isnull((select top 1 col
                         from t t2
                         where t2.id < t.id
                         order by id desc
                        ), 0)
    from t
    

    This uses isnull() instead of coalesce() because of a "bug" in SQL Server that evaluates the first argument twice when using coalesce().

    You can also do this with 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;
    

    All of these assume that you have some column for specifying the ordering. It might be an id, or a creation date or something else. SQL tables are inherently unordered, so there is no such thing as a "previous row" without a column specifying the ordering.

    0 讨论(0)
提交回复
热议问题