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
On first loop value 1 will not be deducted because it has no previous row, which is ok.
Next loop value 2 will then be deducted by the previous row which is value 1. And so on until the last row.
How can I achieve this routine?
By SQL query or VB6 code.Any will do.
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.
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;