So etwas wie das Folgende sollte funktionieren:
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
Dies gibt höchstens zwei Zeilen zurück. Es ist nicht klar, ob Sie datentypisierte Spalten für Datum und Uhrzeit verwenden oder ob Sie tatsächlich reservierte Wörter als Spaltennamen verwenden, also müssen Sie sich darum kümmern. (Ich habe die Zeit weggelassen, aber Sie könnten das einfach zu den verschiedenen Sortierungen und Filterungen hinzufügen.)
Angesichts der überarbeiteten Kriterien wird es etwas kniffliger, da das Einschließen oder Ausschließen einer Zeile von dem Wert abhängt, der in einer anderen Zeile zurückgegeben wird. Hier wird die „zweite“ Zeile, wenn es zwei oder mehr Zeilen gibt, nur dann aufgenommen, wenn die „erste“ Zeile einem bestimmten Wert entspricht. Die Standardmethode hierfür besteht darin, die Daten abzufragen, um den Maximalwert zu erhalten, und sie dann erneut abzufragen, während auf das Ergebnis des ersten Satzes verwiesen wird.
Allerdings kann man mit row_number viele verrückte Dinge anstellen. Daran arbeiten:
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
Sie müssen das Datum/Uhrzeit-Problem lösen, da dies nur mit Datumsangaben funktioniert.