Laravel Eloquent выбрать все строки с максимальным созданием
У меня есть таблица, которая содержит:
id seller_id amount created_at
1 10 100 2017-06-01 00:00:00
2 15 250 2017-06-01 00:00:00
....
154 10 10000 2017-12-24 00:00:00
255 15 25000 2017-12-24 00:00:00
Я хочу получить все последние строки для каждого отдельного seller_id. Я могу получить последнюю строку для одного, как это:
$sales = Snapshot::where('seller_id', '=', 15)
->orderBy('created_at', 'DESC')
->first();
Как получить только последнюю строку для каждого продавца?
3 ответа
Решение
Чтобы получить последнюю запись для каждого seller_id, вы можете использовать следующий запрос
select s.*
from snapshot s
left join snapshot s1 on s.seller_id = s1.seller_id
and s.created_at < s1.created_at
where s1.seller_id is null
Используя конструктор запросов, вы можете переписать его как
DB::table('snapshot as s')
->select('s.*')
->leftJoin('snapshot as s1', function ($join) {
$join->on('s.seller_id', '=', 's1.seller_id')
->whereRaw(DB::raw('s.created_at < s1.created_at'));
})
->whereNull('s1.seller_id')
->get();
Это сработало:
DB::table('snapshot as s')
->select('s.*')
->leftJoin('snapshot as s1', function ($join) {
$join->on('s.seller_id', '=', 's1.seller_id');
$join->on('s.created_at', '<', 's1.created_at');
})
->whereNull('s1.seller_id')
->get();
Следуя ответу в /questions/3184854/kak-sozdat-psevdonim-tablitsyi-v-zaprosah-laravel-eloquent-ili-s-pomoschyu-query-builder/3184880#3184880 , в Laravel 10 вы можете использоватьself::from
вместоDB::table
чтобы получить те же результаты, но с полными моделями, а не только с массивами.
в модели моментального снимка (Snapshot.php)
use Illuminate\Database\Eloquent\Builder;
//...
public function scopeLatestForEachSeller(Builder $query): Builder
{
/**
* In case the table name is modified by code elsewhere,
* we use the table name retrieval method.
*/
$table = $this->getTable();
return self::from($table . ' as s')
->select('s.*')
->leftJoin($table . ' as s1', function ($join) {
$join->on('s.seller_id', '=', 's1.seller_id')
->on('s.created_at', '<', 's1.created_at');
})
->whereNull('s1.seller_id');
}
где-нибудь еще в коде
$snapshots = Snapshot::latestForEachSeller()->get();