You can't do it in the base search, because Splunk sets up the timeframe before it even finds any events. What you could do though is to post-filter the events once they've been returned from the base search.
value=pair earliest=sometime latest=sometime | eventstats earliest(_time) as earliest_time | where _time<relative_time(earliest_time,"+7d")
That works but it is extremely expensive (programming/search cost).
Correct. However as you can't put the logic in at an earlier stage, this is what you're likely stuck with. I suppose you could maybe use a subsearch for generating the correct times, but you're still back to the problem of finding the earliest event. Splunk searches in reverse chronological order so in order to find the earliest event, it has to find all the ones after that anyway.
how about using map to give a time frame for each field-value pair?
| eval time_b4=relative_time(time_anchor, "-1h") | eval time_l8r=relative_time(time_anchor, "+1h") | map search="search index=index1 sourcetype=sourcetype1 field1=$field$ earliest=$time_b4$ latest=$time_l8r$"
Something like that maybe?