Question

I have the following:

Corp_ID   ExpireDate  RecordUpdateDate       Status    State
100       2013/08/02  2013-04-02  00:00:00   Active     CO
100       2013/08/05  2013-08-02  00:00:00   Active     CO
100       2013/08/26  2013-08-05  00:00:00   Closed     NV
100       2013/10/24  2013-08-26  00:00:00   Active     CO   <<<------
100       2013/11/14  2013-10-24  00:00:00   Active     NV
100       12/31/9999  2013-11-14  00:00:00   Active     AZ

I am trying to get the record that corresponds to the expire date 2013/10/24. My goal is to show the moment the current status (active - bottom row) started. The correct return would be 2013/10/24 as that is when the corporation was updated from a status 'closed' to a status 'active'.

The answer is (I think)

select top 1 Y.* from
  (
  select RecordUpdateDate, Status, ExpireDate,
    dense_rank() over (order by RecordUpdateDate desc) as rank
  from [dbo].[Table_1]
  ) X
inner join
  (
  select RecordUpdateDate, Status, ExpireDate,
    dense_rank() over (order by RecordUpdateDate desc) as rank
  from [dbo].[Table_1]
  ) Y
on X.rank = Y.rank- 1  where X.Status <> Y.Status  

Your answers were key!

Was it helpful?

Solution 2

You can use this query. It joins 2 identical subqueries where I used dense_rank() to get the order of record updates and then I get the record where the status changed in the join condition:

select Y.* from
  (
  select RecordUpdateDate, Status, ExpireDate,
    dense_rank() over (order by RecordUpdateDate) as rank
  from table1
  ) X
inner join
  (
  select RecordUpdateDate, Status, ExpireDate,
    dense_rank() over (order by RecordUpdateDate) as rank
  from table1
  ) Y
on X.rank = Y.rank - 1 and X.Status = 'Closed' and Y.Status = 'Active'

SQL Fiddle Demo

OTHER TIPS

This should work on any SQL Server version:

SELECT TOP 1 t1.* FROM t t1
JOIN (
  SELECT ExpireDate FROM t
  WHERE Status = 'Closed'
) t2 ON t1.ExpireDate >= t2.ExpireDate and t1.Status != 'Closed'
ORDER BY t1.ExpireDate

If you are wondering why there is a second check for the Closed and why the ExpireDate is compared using >= instead of > is because this is checking for the Closed status to happen have the same ExpireDate as the immediately Active record after it.

Fiddle here. I've added an extra record in the fiddle with the same date as the Closed one to check this behavior.

Ok, let me start by saying that Szymon's solution is definitely the answer to the question you've made, so it's up to you to mark it as an answer. But, I wanted to express that there are better ways to achieve this from an architectural point of view, the only thing is that it would require you to update your database schema to include a log table which makes it easier to query "events" that has happened in relation to a "company".

Basically, that query from Szymon could get extremely slow if you have a lot of data and little resources in your server. However, if you keep a company log that records every status change and any other thing you want to record, it'd be extremely easy and quick to query this log table without the need for so many joins and sub-queries

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top