Use una combinación de subconsulta:
$days = 10 ;
$currencies = Currency::with(
[
'exchangeRate' => function ($q) use ($days) {
$latest = CurrencyExchangeRate::select('currency_id', 'date')
->selectRaw('MAX(created_at) created_at')
->groupBy('currency_id', 'date');
$q->joinSub($latest, 'latest', function($join) {
$join->on('currency_exchange_rates.currency_id', 'latest.currency_id')
->on('currency_exchange_rates.date', 'latest.date')
->on('currency_exchange_rates.created_at', 'latest.created_at');
})->where('currency_exchange_rates.created_at', ">", strtotime('-' . $days . ' days', time()));
}
]
)->get();
Esto ejecuta la siguiente consulta:
select *
from `currency_exchange_rates`
inner join (
select `currency_id`, `date`, MAX(created_at) created_at
from `currency_exchange_rates`
group by `currency_id`, `date`
) as `latest`
on `currency_exchange_rates`.`currency_id` = `latest`.`currency_id`
and `currency_exchange_rates`.`date` = `latest`.`date`
and `currency_exchange_rates`.`created_at` = `latest`.`created_at`
where `currency_exchange_rates`.`currency_id` in (?, ...)
and `currency_exchange_rates`.`created_at` > ?