I need some guidance and help with a question I am not entirely sure how to solve in SQL Server 2012. I think LAG
and LEAD
functions could be useful but I am not sure.
This is what my data looks right now:
=========================================
YearMonth LocationCode Active
=========================================
201405 123 0
201406 123 2
201409 211 1
201410 211 0
201411 214 0
201412 214 3
We have a YearMonth
column that shows how the status looked like for each locationCode
and an Active
int that represents a quality for each LocationCode
Objective:
My objective is to compare the LocationCode
for for the current YearMonth
(let's call it 201406
) and the previous Yearmonth
(let's call it 201405
):
An example :
=========================================
YearMonth LocationCode Active
=========================================
201405 123 0
201406 123 2
Basically what I am trying to figure out is how to compare the current month's row (201406) to the previous month's row (201405) on the column called Active
.
If the current month's row Active
column is a non-zero and the previous month's Active was a zero, then we conclude the current month's row to be "New" (1) else (0).
An example is provided below:
==================================================
YearMonth LocationCode Active New
===================================================
201405 123 0 0
201406 123 2 1
201409 211 1 0
201410 211 0 0
201411 214 0 0
201412 214 3 1
How can I solve this problem?
Overview of SQL Server LAG() function In other words, by using the LAG() function, from the current row, you can access data of the previous row, or the row before the previous row, and so on. The LAG() function can be very useful for comparing the value of the current row with the value of the previous row.
LAG provides access to a row at a given physical offset that comes before the current row. Use this analytic function in a SELECT statement to compare values in the current row with values in a previous row.
I think you can use a query like this:
SELECT *,
CASE
WHEN Active <> 0 AND
ISNULL(LAG(Active) OVER (PARTITION BY LocationCode ORDER BY YearMonth), 0) = 0 THEN 1
ELSE 0
END As New
FROM yourTable;
[SQL Fiddle Demo]
You can do this with ROW_NUMBER() OVER
like this:
WITH RankedCodesHistory AS (
SELECT
YearMonth,
LocationCode,
Active,
ROW_NUMBER() OVER (PARTITION BY LocationCode, CASE WHEN Active > 0 THEN 1 ELSE 0 END
ORDER BY LocationCode, YearMonth, Active) rn
FROM CodesHistory)
SELECT
YearMonth,
LocationCode,
Active,
CASE WHEN Active > 0 AND rn = 1 THEN 1 ELSE 0 END AS New
FROM RankedCodesHistory
SQL Fiddle
I have extended your data sample in the Fiddle to demonstrate what will happen if Active goes back to zero and becomes positive second time --- in this case code above will not set corresponding row as new.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With