gpt4 book ai didi

Laravel Eloquent 获取分组行的最新行

转载 作者:行者123 更新时间:2023-12-04 03:01:19 24 4
gpt4 key购买 nike

使用 Eloquent,试图找到一种方法来获取每行的最新行,这些行按以下分组:exchange、base、quote

数据

exchange    base    quote   price   value   created_at

bittrex BTC USD 10000 10000 2018-01-05
bittrex BTC USD 9000 9000 2018-01-01
poloniex BTC USD 10001 10001 2018-01-05
poloniex BTC USD 9000 9000 2018-01-01
binance BTC USD 10002 10002 2018-01-05
binance BTC USD 9000 9000 2018-01-01
binance ETH USD 800 800 2018-01-05
binance ETH USD 700 700 2018-01-01

结果:

bittrex     BTC     USD     10000   10000   2018-01-05
poloniex BTC USD 10001 10001 2018-01-05
binance BTC USD 10002 10002 2018-01-05
binance ETH USD 800 800 2018-01-05

更新

我选择了@Cryode 解决方案,原始 SQL 而不是 Eloquent(如果有人能想出一个 Eloquent 查询来复制下面查询的结果,请随时发布)。

我还更改了表的结构以添加 id(增量)作为主键。我还添加了以下索引 $table->index(['exchange', 'base', 'quote', 'created_at']);

解决方法如下:

$currencies  = DB::select('SELECT *
FROM (
SELECT DISTINCT exchange, base, quote
FROM tickers
) AS t1
JOIN tickers
ON tickers.id =
(
SELECT id
FROM tickers AS t2
WHERE t2.exchange = t1.exchange
AND t2.base = t1.base
AND t2.quote = t1.quote
ORDER BY created_at DESC
LIMIT 1
)
');

谢谢

最佳答案

让我们首先确定这个 SQL 查询实际上是什么样的。

This DBA answer提供了对“每组最大 n”问题的一些深刻见解,以及 PostgreSQL 和 MySQL 示例。受此答案的启发,这是我为您的单表(假设 MySQL 作为您的数据库)提出的建议:

SELECT ticker.*
FROM (
SELECT DISTINCT exchange, base, quote
FROM ticker
) AS exchanges
JOIN ticker
ON ticker.id =
(
SELECT id
FROM ticker
WHERE ticker.exchange = exchanges.exchange
AND ticker.base = exchanges.base
AND ticker.quote = exchanges.quote
ORDER BY created_at DESC
LIMIT 1
);

亲爱的。将其纳入 Laravel 语言看起来并不容易。

就我个人而言,我什至不会尝试。复杂的 SQL 查询只是因为它们利用您的数据库来进行报告、数据收集等。试图将其插入查询构建器是乏味的,而且可能几乎没有任何好处。

也就是说,如果您想使用 Laravel 的查询构建器和 Eloquent 以简单的方式获得相同的结果,这里有一个选项:

// Get the unique sets of tickers we need to fetch.
$exchanges = DB::table('ticker')
->select('exchange, base, quote')
->distinct()
->get();

// Create an empty collection to hold our latest ticker rows,
// because we're going to fetch them one at a time. This could be
// an array or however you want to hold the results.
$latest = new Collection();

foreach ($exchanges as $exchange) {
$latest->add(
// Find each group's latest row using Eloquent + standard modifiers.
Ticker::where([
'exchange' => $exchange->exchange,
'base' => $exchange->base,
'quote' => $exchange->quote,
])
->latest()
->first()
);
}

优点:您可以使用查询构建器和 Eloquent 抽象;允许您维护您的 Ticker 模型,该模型在请求期间可能需要额外的逻辑。

缺点:需要多次查询。


另一种选择是使用 MySQL View封装复杂的查询,并创建一个单独的 Eloquent 模型,该模型将从该 View 中获取。这样,您的应用程序代码就可以像 TickerLatest::all() 一样简单。

关于Laravel Eloquent 获取分组行的最新行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48958737/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com