Noget i stil med følgende burde virke:
SELECT ID, Date, Time, Status
from (select ID, Date, Time, Status, row_number() over (order by Date) Ranking
from MyTable
where ID = @SearchId
and Date <= @SearchDate) xx
where Ranking < 3
order by Date, Time
Dette vil højst returnere to rækker. Det er ikke klart, om du bruger Dato- og Tidsdatatypede kolonner, eller om du rent faktisk bruger reserverede ord som kolonnenavne, så du bliver nødt til at bøvle med det. (Jeg har udeladt Time, men det kan du sagtens tilføje til de forskellige bestillinger og filtreringer.)
I betragtning af de reviderede kriterier bliver det en smule vanskeligere, da inkluderingen eller ekskluderingen af en række afhænger af den værdi, der returneres i en anden række. Her er den "anden" række, hvis der er to eller flere rækker, kun inkluderet, hvis den "første" række er lig med en bestemt værdi. Standardmåden at gøre dette på er at forespørge dataene for at få den maksimale værdi og derefter forespørge på det igen, mens du refererer til resultatet af det første sæt.
Du kan dog gøre en masse skæve ting med række_nummer. Arbejd på dette:
SELECT ID, Date, Time, Status
from (select
ID, Date, Time, Status
,row_number() over (partition by case when Date = @SearchDate then 0 else 1 end
order by case when Date = @SearchDate then 0 else 1 end
,Date) Ranking
from MyTable
where ID = @SearchId
and Date <= @SearchDate) xx
where Ranking = 1
order by Date, Time
Du bliver nødt til at løse problemet med dato/klokkeslæt, da dette kun virker mod datoer.