【问题标题】:Get second highest date from related table从相关表中获取第二高的日期
【发布时间】:2020-04-06 23:17:39
【问题描述】:

我正在尝试使用 Eloquent Laravel 6 从关系表中获取第二高的日期。

MoodTable
id    animal_id  date          mood
1     1          2019-12-14    happy
2     1          2019-12-11    drunk
3     1          2019-12-13    sad

AnimalTable
id    name
1     Dog

因此,例如,我希望能够查询:“今天狗很开心。之前他喝醉了。

获取我使用的最高值:

return $this->hasMany('App\AnimalMood', 'animal_id')->select(DB::raw('
                    mood,
                    animal_id,
                    MAX(date) as max_date,  
                    '))
                 ->groupBy('stock_id');

但是,说到第二个最高约会……我出去了……

我看过How to return second newest record in SQL? 对于一些答案,但无法将其放在关系中,也无法将其翻译为 Eloquent。

理想情况下,我想从我的控制器运行 Animal::with('moodPrevious')->get()Animal::find(1)->moodPrevious...

【问题讨论】:

  • 您可以对子查询进行计数,该子查询会计算高于当前日期的日期。如果计数为 1,则您的排名第二。

标签: mysql laravel date eloquent


【解决方案1】:

当您查询时,我会更改关系并将所有相关模型抓取到您的 Animal 模型。

return $this->hasMany('App\AnimalMood', 'animal_id');

下面返回带有预先排序的情绪的动物。

$animals = Animal::with(['mood' => function($q){
               $q->orderByDesc('date');
           }])->get();

Laravel 提供了很多与相关模型配合良好的收集方法。我会使用您可以提供给first() 的回调来获得您想要的模型情绪。您可能已经有了您想要的特定模型,或者通过对上述集合或类似的东西进行遍历。该关系将是一个collection 实例,因此我们使用集合方法来获取所需的mood

$previousMood = $animal->mood->first(function($value, $key){
    return $key == 1 // You can use whatever here, this will return the second item on the relation, or the previous mood.
});

请参阅https://laravel.com/docs/5.8/collections#method-first 以获取参考。

【讨论】:

  • 它会起作用的,谢谢。然而,Animal 表有大约 300 行,Mood 表每天更新。这意味着在一年的时间里,我会在查询中放入 109500 行......这会降低很多性能,不是吗?
  • 视情况而定。如果您需要一整年的完整报告,这可能需要一些时间,但无论您如何分割它都会发生这种情况。如果性能成为问题,您可以限制初始查询以减少返回的总数。
【解决方案2】:

我认为这可行

return $this->hasMany('App\AnimalMood', 'animal_id')
    ->select(
        DB::raw('
            mood,
            animal_id,
            MAX(date) as max_date,  
        ')
    )
    ->where(
        DB::raw("
            date = (
                SELECT 
                    MAX(date) 
                FROM animal_moods 
                WHERE date < (
                    SELECT 
                        MAX(date) 
                    FROM 
                    animal_moods
                )
            )
        ")
    )
    ->groupBy('stock_id');

【讨论】:

  • 这不是一个可扩展的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 2011-07-18
  • 2021-09-08
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多