Subtracting Previous Value by Prior Group - SQL Server
By using a CTE you would be able to get the data ordered, and then select the previous record.
WITH PREVCTE AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY SN ORDER BY MyDate) [RowNum]
FROM @myTable
)
SELECT A.SN,
A.MyDate,
A.[Value],
A.[Value] - COALESCE(B.[Value], A.[Value]) [Consumption]
FROM PREVCTE A LEFT OUTER JOIN PREVCTE B
ON A.RowNum - 1 = B.RowNum AND
A.SN = B.SN
SQL Fiddle Demo
Subtract previous row value to current row
DECLARE @Test TABLE (
id int,
value int,
acc_no int
)
INSERT @Test(id, value, acc_no)
VALUES
(1, 12, 1),
(2, 14, 1),
(3, 15, 1),
(4, 10, 2),
(5, 16, 2),
(6, 19, 1),
(7, 7, 3),
(8, 24, 2)
SELECT id, t.value, acc_no, t.value - ISNULL(v.value, 0) AS result
FROM @Test t
OUTER APPLY (
SELECT TOP (1) value
FROM @Test
WHERE id < t.id
AND acc_no = t.acc_no
ORDER by id DESC
) v
How can I subtract a previous row in sql?
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.
Related Topics
Get Day of Week in SQL Server 2005/2008
Spark SQL Window Function With Complex Condition
How to Get the Difference in Years from Two Different Dates
SQL Server: Make All Upper Case to Proper Case/Title Case
SQL Server - Stop or Break Execution of a SQL Script
Sql: Repeat a Result Row Multiple Times, and Number the Rows
Updating Table Rows in Postgres Using Subquery
Using Isnull VS Using Coalesce for Checking a Specific Condition
SQL Query Replace Null Value in a Row with a Value from the Previous Known Value
Check If MySQL Table Exists Without Using "Select From" Syntax
Group by Behavior When No Aggregate Functions Are Present in the Select Clause
When No 'Order By' Is Specified, What Order Does a Query Choose For Your Record Set
SQL Switch/Case in 'Where' Clause
How to Count Items in Comma Separated List MySQL
How to Fetch the Row Count for All Tables in a SQL Server Database