在 laravel 11 / mysql 8 应用程序中
货币模型有方法:
public function latestCurrencyHistory(): HasMany
{
return $this->hasMany(CurrencyHistory::class)->latest();
}
并根据要求:
$this->currencies = Currency
::getByActive(CurrencyActiveEnum::ACTIVE)
->with('latestCurrencyHistory')
->orderBy('ordering', 'asc')
->get();
我看到了 sql 跟踪:
SELECT *
FROM `currencies`
WHERE `active` = '1'
ORDER BY `ordering` asc
SELECT *
FROM ( SELECT *, row_number() over (partition by `currency_histories`.`currency_id`
ORDER BY `created_at` desc) AS `laravel_row`
FROM `currency_histories`
WHERE `currency_histories`.`currency_id` in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31)) AS `laravel_table`
WHERE `laravel_row` <= 1
ORDER BY `laravel_row`
我尝试通过添加
->limit
来仅读取最后一行:
public function latestCurrencyHistory(): HasMany
{
return $this->hasMany(CurrencyHistory::class)->latest()->limit(1);
}
但是生成的sql是一样的。看起来
->limit
在这里不起作用。
是否有办法只获取最后一行 1? 我可以在CurrencyHistory.created_at> =过去24小时添加1个附加过滤器吗?
您可以修改查询以直接获取最新的货币历史记录,而不是限制在关系方法中,同时避免急切加载所有行的开销:
public function latestCurrencyHistory(): HasOne
{
return $this->hasOne(CurrencyHistory::class)->latestOfMany();
}
latestOfMany() 方法是 Laravel 中获取 HasMany 关系的最新记录的一种特殊方法。它会自动按时间戳(例如,created_at)对相关记录进行排序,并仅选择最新的记录。
然后
$this->currencies = Currency::getByActive(CurrencyActiveEnum::ACTIVE)
->with('latestCurrencyHistory')
->orderBy('ordering', 'asc')
->get();