Något i stil med följande borde fungera:
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
Detta kommer att returnera högst två rader. Det är inte klart om du använder datatypade kolumner för datum och tid, eller om du faktiskt använder reserverade ord som kolumnnamn, så du måste krångla till det. (Jag utelämnade Time, men du kan enkelt lägga till det i de olika beställningarna och filtreringarna.)
Med tanke på de reviderade kriterierna blir det lite knepigare, eftersom inkluderingen eller exkluderingen av en rad beror på värdet som returneras i en annan rad. Här inkluderas den "andra" raden, om det finns två eller flera rader, endast om den "första" raden är lika med ett visst värde. Det vanliga sättet att göra detta är att fråga data för att få maxvärdet och sedan fråga igen samtidigt som du refererar till resultatet av den första uppsättningen.
Däremot kan du göra en hel del knäppa saker med row_number. Arbeta med detta:
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 måste lösa datum/tid-problemet, eftersom detta bara fungerar mot datum.