Algo como lo siguiente debería funcionar:
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
Esto devolverá como máximo dos filas. No está claro si está utilizando columnas con tipos de datos de fecha y hora, o si realmente está utilizando palabras reservadas como nombres de columna, por lo que tendrá que preocuparse por eso. (Omití el tiempo, pero podrías agregarlo fácilmente a los diversos pedidos y filtros).
Dados los criterios revisados, se vuelve un poco más complicado, ya que la inclusión o exclusión de una fila depende del valor devuelto en una fila diferente. Aquí, la "segunda" fila, si hay dos o más filas, se incluye solo si la "primera" fila es igual a un valor particular. La forma estándar de hacer esto es consultar los datos para obtener el valor máximo y luego volver a consultarlos mientras se hace referencia al resultado del primer conjunto.
Sin embargo, puedes hacer muchas cosas complicadas con número_de_fila. Trabaja en esto:
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
Tendrá que resolver el problema de fecha/hora, ya que esto solo funciona contra fechas.