Qualcosa come il seguente dovrebbe funzionare:
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
Questo restituirà al massimo due righe. Non è chiaro se stai utilizzando colonne con tipi di dati Data e Ora o se stai effettivamente utilizzando parole riservate come nomi di colonne, quindi dovrai preoccuparti di quello. (Ho tralasciato il tempo, ma potresti facilmente aggiungerlo ai vari ordinamenti e filtri.)
Dati i criteri rivisti, diventa un po' più complicato, poiché l'inclusione o l'esclusione di una riga dipende dal valore restituito in una riga diversa. Qui, la "seconda" riga, se sono presenti due o più righe, viene inclusa solo se la "prima" riga corrisponde a un determinato valore. Il modo standard per farlo è interrogare i dati per ottenere il valore massimo, quindi interrogarli di nuovo facendo riferimento al risultato del primo set.
Tuttavia, puoi fare molte cose stravaganti con row_number. Lavora su questo:
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
Dovrai risolvere il problema di data/ora, poiché funziona solo rispetto alle date.