現在の行を前の行から減算したい場合、何を問い合わせればよいですか。私は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()
を使用します。SQLServerには「バグ」があり、coalesce()
を使用すると最初の引数が2回評価されるためです。
これは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;