patternsqlModerate
Getting each status change in a table
Viewed 0 times
eachgettingstatuschangetable
Problem
I have a table that holds status changes per item. The item can go in and out of a status multiple times.
ItemTable (ItemId int, Status varchar(50), DateOfChange date)
I need to pull the date of each change. However, since the statuses can be repeated for each Item, I can't just do the min(DateOfChange) and find the occurrences.
This is in an OLAP environment, and the subquery that's been used to pull this data is KILLING performance.
Is there a way to pull this stuff via partitioning/rownumber functions? Or something else that would behave better in OLAP? (This is in SQL 2008.)
ItemTable (ItemId int, Status varchar(50), DateOfChange date)
I need to pull the date of each change. However, since the statuses can be repeated for each Item, I can't just do the min(DateOfChange) and find the occurrences.
This is in an OLAP environment, and the subquery that's been used to pull this data is KILLING performance.
Is there a way to pull this stuff via partitioning/rownumber functions? Or something else that would behave better in OLAP? (This is in SQL 2008.)
Solution
This type of requirement comes under the banner of "gaps and islands". A popular approach is
WITH T
AS (SELECT *,
DENSE_RANK() OVER (PARTITION BY ItemId ORDER BY DateOfChange) -
DENSE_RANK() OVER (PARTITION BY ItemId, Status ORDER BY DateOfChange) AS Grp
FROM ItemTable)
SELECT ItemId,
Status,
MIN(DateOfChange) AS Start,
MAX(DateOfChange) AS Finish
FROM T
GROUP BY ItemId,
Status,
Grp
ORDER BY StartCode Snippets
WITH T
AS (SELECT *,
DENSE_RANK() OVER (PARTITION BY ItemId ORDER BY DateOfChange) -
DENSE_RANK() OVER (PARTITION BY ItemId, Status ORDER BY DateOfChange) AS Grp
FROM ItemTable)
SELECT ItemId,
Status,
MIN(DateOfChange) AS Start,
MAX(DateOfChange) AS Finish
FROM T
GROUP BY ItemId,
Status,
Grp
ORDER BY StartContext
StackExchange Database Administrators Q#56593, answer score: 10
Revisions (0)
No revisions yet.