给出下表
id short_name long_name category departure rec_order
1548 AAA AAA AA station 10:00 1
1548 BBB BBB BB station 11:10 2
1548 CCC CCC CC station 12:30 3
1548 DDD DDD DD border 15:30 4
我想只访问边框前的最后一行(电台)。 基本上只返回
CCC CCC CC station 12:30 3
因为数据库相当大,甚至这个时间表在现实生活中是一个复杂的结构,我们在索引视图中将所有数据放在一起(这里是为了示例的简化)我正在寻找一个更高性能的解决方案(可能没有交叉连接)。
我已尝试使用滞后和/或导联以及偏移提取进行选择,但是当我放入where子句where category = 'border'
时,这些解决方案不能正常工作,因为它只选择边框行。 / p>
此查询正在运行,但我正在寻找更优化的解决方案:
select top 1 M1.short_name M1.long_name
from V_TIMETABLE M1 WITH ( NOEXPAND )
join
(
select top 1 rec_order, id
from V_TIMETABLE V WITH ( NOEXPAND )
where V.id = 1548
and category = 'border'
order by rec_order desc
) M2 on M1.id = M2.id
where M1.rec_order < M2.rec_order
order by M1.rec_order desc
答案 0 :(得分:4)
这适用于给定数据
;with cte
as
(
select
id, short_name , long_name, category , departure , rec_order,
row_number() over (partition by id order by departure desc) as rownum
from table where category<>'border'
)
select * from cte where rownum=1
答案 1 :(得分:2)
我只想指出另一种解决方案:
select t.*
from (select t.*,
lead(category) over (partition by id order by departure) as next_category
from t
) t
where next_category = 'border';
重要提示:这不会返回没有边框的id
。它还会为多次有边框的id
返回多行。这些似乎更符合实际问题而不是总是选择一行 - 并且与问题中提供的示例代码一致。