我有一张桌子可以跟踪每个州的车辆停靠情况。例如,车辆可以在一个状态中进行多次停止,进入另一个状态,然后在给定的一天中返回到相同的状态。以下是我的意思的样本:
VehicleID | State | LocationDate | EventType
-------------------------------------------------------
1 | KY | 2013-02-10 05:09:00.000 | Delivery
1 | KY | 2013-02-10 05:45:00.000 | Delivery
1 | KY | 2013-02-10 06:10:00.000 | Gas
1 | IN | 2013-02-10 08:33:00.000 | Delivery
1 | KY | 2013-02-10 10:13:00.000 | Delivery
我希望按时间顺序获得每个州的第一次和最后一次停留时间。如果列表中下一个状态只有一行,则再次列出该行。例如,我正在寻找以下内容:
VehicleID | State | LocationDate | FirstOrLast
---------------------------------------------------------
1 | KY | 2013-02-10 05:09:00.000 | First
1 | KY | 2013-02-10 06:10:00.000 | Last
1 | IN | 2013-02-10 08:33:00.000 | First
1 | IN | 2013-02-10 08:33:00.000 | Last
1 | KY | 2013-02-10 10:13:00.000 | First
1 | KY | 2013-02-10 10:13:00.000 | Last
答案 0 :(得分:0)
基本上,您要为连续状态添加分组标识符。您可以使用行号的差异来执行此操作。这是识别连续行组的一种聪明方法。
然后,根据该信息,您可以使用row_number()
获取所需信息。因为您希望重复行,所以我建议使用union all
方法:
with g as (
select t.*,
row_number() over (partition by vehicleId, grp, state order by LocationDate) as seqnum_asc,
row_number() over (partition by vehicleId, grp, state order by LocationDate desc) as seqnum_desc
from (select t.*,
(row_number() over (partition by VehicleID order by LocationDate) -
row_number() over (partition by VehicleID, State order by LocationDate)
) as grp
from t
) t
)
select g.*, 'First' as FirstOrLast
from g
where seqnum_asc = 1
union all
select g.*, 'Last' as FirstOrLast
from g
where seqnum_desc = 1;