user46372
user46372

Reputation: 159

SQL query to get status as of a given date

I'm sure this has been answered before but couldn't find it.

I have a table of items which change status every few weeks. I want to look at an arbitrary day and figure out how many items were in each status.

For example:

tbl_ItemHistory

ItemID
StatusChangeDate
StatusID

Sample data:

1001, 1/1/2010, 1
1001, 4/5/2010, 2
1001, 6/15/2010, 4
1002, 4/1/2010, 1
1002, 6/1/2010, 3
...

So I need to figure out how many items were in each status for a given day. So on 5/1/2010, there was one item (1001) in status 2 and one item in status 1 (1002).

Since these items don't change status very often, maybe I could create a cached table every night that has a row for every item and every day of the year? I'm not sure if that's best or how to do that though

I'm using SQL Server 2008R2

Upvotes: 1

Views: 3103

Answers (1)

Gordon Linoff
Gordon Linoff

Reputation: 1271091

For an arbitrary day, you can do something like this:

select ih.*
from (select ih.*,
             row_number() over (partition by itemId order by StatusChangeDate desc) as seqnum
      from tbl_ItemHistory ih
      where StatusChangeDate <= @YOURDATEGOESHERE
     ) ih
where seqnum = 1

The idea is to enumerate all the history records for each on or before the date,using row_nubmer. The ordering is in reverse chronological order, so the most recent record -- on or before the date -- has a value of 1.

The query then just chooses the records whose value is 1.

To aggregate the results to get each status for the date, use:

select statusId, count(*)
from (select ih.*,
             row_number() over (partition by itemId order by StatusChangeDate desc) as seqnum
      from tbl_ItemHistory ih
      where StatusChangeDate <= @YOURDATEGOESHERE
     ) ih
where seqnum = 1
group by StatusId

Upvotes: 3

Related Questions