如何限制 hasMany 与最后一行 1 的关系?

问题描述 投票:0回答:1

在 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个附加过滤器吗?

mysql laravel eloquent
1个回答
0
投票

您可以修改查询以直接获取最新的货币历史记录,而不是限制在关系方法中,同时避免急切加载所有行的开销:

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();
    
© www.soinside.com 2019 - 2024. All rights reserved.