我有以下内容:
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
我正在尝试获取与过期日期2013/10/24
对应的记录。我的目标是显示当前状态(活动 - 底行)的开始时刻。正确的回报是2013/10/24
,因为当公司从“已关闭”状态更新为“有效”状态时。
答案是(我认为)
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
你的答案很关键!
答案 0 :(得分:1)
这适用于任何SQL Server版本:
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
如果您想知道为什么对Closed
进行第二次检查以及使用ExpireDate
代替>=
来比较>
的原因是因为这是检查发生的Closed
状态与之后的ExpireDate
记录具有相同的Active
。
小提琴here。我在小提琴中添加了一条额外的记录,其日期与Closed
相同,以检查此行为。
答案 1 :(得分:0)
您可以使用此查询。它加入了两个相同的子查询,我使用dense_rank()
来获取记录更新的顺序,然后我得到状态在连接条件中更改的记录:
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'
答案 2 :(得分:0)
好的,首先让我说Szymon的解决方案肯定是你所提问题的答案,所以你可以将它标记为答案。但是,我想表达从架构的角度来看有更好的方法来实现这一点,唯一的事情是它需要你更新你的数据库模式以包含一个日志表,这使得查询“事件”更容易与“公司”有关。
基本上,如果您的服务器中有大量数据和资源很少,那么来自Szymon的查询可能会变得非常慢。但是,如果您保留一个记录每个状态更改的公司日志以及您要记录的任何其他内容,那么查询此日志表非常容易且快速,而无需如此多的连接和子查询