Assuming I understand that you want the row that has the minimum absolute difference between start_date and today() (so, MIN(ABS(START_DATE-TODAY()))
), you can do a somewhat messy query using the having clause this way:
data have;
do id = 2 to 9;
do start_date = '02MAR2016'd to '31MAR2016'd by id;
output;
end;
end;
run;
proc sql;
select id, start_date format=date9.
from have
group by id
having abs(start_date-today()) = min(abs(start_date-today()));
quit;
I don't like this in part because it's non-standard SQL and gives a note about re-merging data (it's non-standard and gives you that note because you're using a value that's not really available in a group by), and in part because it gives you multiple rows if two are tied (see id=4 if you run this on 3/16/2016).
A correlated subquery version, which at least avoids the remerging note (but actually does effectively the same thing):
proc sql;
select id, start_date format=date9.
from have H
where abs(start_date-today()) = (
select min(abs(start_date-today()))
from have V
where H.id=V.id
);
quit;
Still gives two for id=4 though (on 3/16/2016). You'd have to make a way to pick if there are possibly two answers (or perhaps you want strictly less than?). This does a subquery to determine what the smallest difference is then returns it.