首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Laravel雄辩地获得了最新的分组行

Laravel雄辩地获得了最新的分组行
EN

Stack Overflow用户
提问于 2018-02-24 02:28:52
回答 5查看 6.1K关注 0票数 3

使用雄辩,试图找到一种方法,以获得每一行的最新行分组: exchange,base,引号

数据

代码语言:javascript
运行
复制
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

结果:

代码语言:javascript
运行
复制
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,而不是雄辩的SQL(如果有人可以提出一个雄辩的查询来复制下面查询的结果,请随意发布)。

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

以下是解决办法:

代码语言:javascript
运行
复制
$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
                                 )
                         ');

谢谢

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2018-02-25 06:50:52

让我们首先确定这个SQL查询的实际外观。

这个DBA的回答为“每个组中最大的n个组”问题提供了一些很好的见解,以及PostgreSQL和MySQL示例。在这个答案的启发下,我为您的单个表(假设MySQL为您的DB)提供了如下内容:

代码语言:javascript
运行
复制
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
       );

哦,亲爱的。把它讲给拉勒维尔听看来不容易。

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

尽管如此,如果您希望使用Laravel的查询生成器和雄辩器以简单的方式获得相同的结果,下面是一个选项:

代码语言:javascript
运行
复制
// 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()
    );
}

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

缺点:需要多个查询。

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

票数 6
EN

Stack Overflow用户

发布于 2018-02-24 07:23:52

您可以先获取最新的行,然后对集合进行分组。

代码语言:javascript
运行
复制
$items = Ticker::latest()->get();
// exchange, base, quote
$groupedByExchange = $items->groupBy('exchange');
$groupedByBase = $items->groupBy('base');
$groupedByQoute = $items->groupBy('qoute');

UPDATE:您可以通过简单地在->first()函数之后添加groupBy()来获得每个组的单个项。

代码语言:javascript
运行
复制
$latestByExchange= Ticker::latest()->groupBy('exchange')->first(); // and so on
票数 0
EN

Stack Overflow用户

发布于 2018-02-24 08:09:06

可以将多个参数传递给groupBy方法,以按多列分组。

请参阅https://laravel.com/docs/5.6/queries#ordering-grouping-limit-and-offset文档

代码语言:javascript
运行
复制
$users = DB::table('users')
            ->groupBy('first_name', 'status')
            ->having('account_id', '>', 100)
            ->get();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48958737

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档