在SQL空间(特别是T-SQL,SQL Server 2008)中,给出以下值列表:
Status Date
------ -----------------------
ACT 2012-01-07 11:51:06.060
ACT 2012-01-07 11:51:07.920
ACT 2012-01-08 04:13:29.140
NOS 2012-01-09 04:29:16.873
ACT 2012-01-21 12:39:37.607 <-- THIS
ACT 2012-01-21 12:40:03.840
ACT 2012-05-02 16:27:17.370
GRAD 2012-05-19 13:30:02.503
GRAD 2013-09-03 22:58:48.750
从此查询生成:
SELECT Status, Date
FROM Account_History
WHERE AccountNumber = '1234'
ORDER BY Date
此特定对象的状态在ACT开始,然后更改为NOS,然后更改为ACT,然后更改为GRAD。
从最新的&#34;组&#34;获得最短日期的最佳方法是什么?状态=&#39; ACT&#39;?
的记录答案 0 :(得分:3)
这是一个执行此操作的查询,通过识别学生状态相同的组,然后使用简单聚合:
select top 1 StudentStatus, min(WhenLastChanged) as WhenLastChanged
from (SELECT StudentStatus, WhenLastChanged,
(row_number() over (order by "date") -
row_number() over (partition by studentstatus order by "date)
) as grp
FROM Account_History
WHERE AccountNumber = '1234'
) t
where StudentStatus = 'ACT'
group by StudentStatus, grp
order by WhenLastChanged desc;
row_number()
函数根据date
在行组内分配序号。对于您的数据,两个row_numbers()
及其区别在于:
Status Date
------ -----------------------
ACT 2012-01-07 11:51:06.060 1 1 0
ACT 2012-01-07 11:51:07.920 2 2 0
ACT 2012-01-08 04:13:29.140 3 3 0
NOS 2012-01-09 04:29:16.873 4 1 3
ACT 2012-01-21 12:39:37.607 5 4 1
ACT 2012-01-21 12:40:03.840 6 5 1
ACT 2012-05-02 16:27:17.370 7 6 1
GRAD 2012-05-19 13:30:02.503 8 1 7
GRAD 2013-09-03 22:58:48.750 9 2 7
请注意,对于具有相同状态的行,最后一行是常量。
聚合将这些组合在一起,并选择最新的top 1 . . . order by date desc
个第一个日期(min(date)
)。
编辑:
查询很容易调整多个帐号。我可能应该以这种方式开始,除了最后的选择比较棘手。此结果包含每个状态和帐户的日期:
select StudentStatus, min(WhenLastChanged) as WhenLastChanged
from (SELECT StudentStatus, WhenLastChanged, AccountNumber
(row_number() over (partition by AccountNumber order by WhenLastChanged) -
row_number() over (partition by AccountNumber, studentstatus order by WhenLastChanged)
) as grp
FROM Account_History
) t
where StudentStatus = 'ACT'
group by AccountNumber, StudentStatus, grp
order by WhenLastChanged desc;
但是你不能轻易地获得每个帐户的最后一个。另一级子查询:
select AccountNumber, StudentStatus, WhenLastChanged
from (select AccountNumber, StudentStatus, min(WhenLastChanged) as WhenLastChanged,
row_number() over (partition by AccountNumber, StudentStatus order by min(WhenLastChanged) desc
) as seqnum
from (SELECT AccountNumber, StudentStatus, WhenLastChanged,
(row_number() over (partition by AccountNumber order by WhenLastChanged) -
row_number() over (partition by AccountNumber, studentstatus order by WhenLastChanged)
) as grp
FROM Account_History
) t
where StudentStatus = 'ACT'
group by AccountNumber, StudentStatus, grp
) t
where seqnum = 1;
这使用聚合以及窗口函数row_number()
。这是为组分配序列号(聚合后),每个帐户的最后日期值为1(order by min(WhenLastChanged) desc
)。最外面的select
然后只为每个帐户选择该行。
答案 1 :(得分:1)
SELECT [Status], MIN([Date])
FROM Table_Name
WHERE [Status] = (SELECT [Status]
FROM Table_Name
WHERE [Date] = (SELECT MAX([Date])
FROM Table_Name)
)
GROUP BY [Status]
在这里试试 Sql Fiddle
答案 2 :(得分:0)
霍根:基本上,是的。我只是想知道日期/时间 帐号上次更改为ACT。以上几点后的记录 标记为这只是额外的。
我们可以寻找第一次状态更改,然后从中选择act(和max),而不只是寻找行为。
所以...每次状态改变时:
with rownumb as
(
select *, row_number() OVER (order by date asc) as rn
)
select status, date
from rownumb A
join rownumb B on A.rn = B.rn-1
where a.status != b.status
现在找到行为项目的最大值。
with rownumb as
(
select *, row_number() OVER (order by date asc) as rn
), statuschange as
(
select status, date
from rownumb A
join rownumb B on A.rn = B.rn-1
where a.status != b.status
)
select max(date)
from satuschange
where status='Act'