Another way to refer to the previous row in an SQL query is to use a recursive common table expression (CTE):
CREATE TABLE t (counter INTEGER);
INSERT INTO t VALUES (1),(2),(3),(4),(5);
WITH cte(counter, previous, difference) AS (
-- Anchor query
SELECT MIN(counter), 0, MIN(counter)
FROM t
UNION ALL
-- Recursive query
SELECT t.counter, cte.counter, t.counter - cte.counter
FROM t JOIN cte ON cte.counter = t.counter - 1
)
SELECT counter, previous, difference
FROM cte
ORDER BY counter;
Result:
counter |
previous |
difference |
1 |
0 |
1 |
2 |
1 |
1 |
3 |
2 |
1 |
4 |
3 |
1 |
5 |
4 |
1 |
The anchor query generates the first row of the common table expression cte
where it sets cte.counter
to column t.counter
in the first row of table t
, cte.previous
to 0, and cte.difference
to the first row of t.counter
.
The recursive query joins each row of common table expression cte
to the previous row of table t
. In the recursive query, cte.counter
refers to t.counter
in each row of table t
, cte.previous
refers to cte.counter
in the previous row of cte
, and t.counter - cte.counter
refers to the difference between these two columns.
Note that a recursive CTE is more flexible than the LAG and LEAD functions because a row can refer to any arbitrary result of a previous row. (A recursive function or process is one where the input of the process is the output of the previous iteration of that process, except the first input which is a constant.)
I tested this query at SQLite Online.