我正在寻找一种方法(最好使用Laravel的查询生成器)仅联接两个具有一对多关系的表上的“最新行”。
这是我的意思的简化示例:
Table 1 - robots
robotID
name
Table 2 - locations
locationID
robotID
latitude
longitude
date (Y-m-d)
我想要一个robots
列表,其中仅包含locations
的最新行(按locations.date
排序)。
我发现这听起来很简单(因此答案可能很明显!),但是如果不使用for循环,这是非常慢的,我将无法轻易获得预期的结果。
期望的结果最好是每个robot
及其最近的location
。我已经尝试了以下方法,但是没有达到预期的效果。我可能会过得很慢。
Robot::whereIn('robots.robotID', [1,2,3,4])
->leftJoin('locations', function ($join) {
$join->on('locations.robotID', '=', 'robots.robotID');
})
->orderBy('locations.date', 'desc')
->groupBy('robots.robotID')
->get();
谢谢!
答案 0 :(得分:2)
groupBy
并不是要那样使用。分组依据是指为了聚合的目的而创建数据组。如果按列分组,则所有其他未聚合列的列值是任意的,不一定与其他列匹配,这很不好。您需要大量修改逻辑才能实现所需的功能,或者可以使用Eloquent relationships来获取具有最新相关位置的机器人作为关系条目。
我将建议后者,因为它在OOP代码中看起来要好得多(不一定是因为它更好或更快速)。
诚然,此解决方案有点笨拙,并且有一个主要缺点。该查询仍会在后台获取所有模型,但每个机器人只会匹配一个模型。
在模型中定义您的关系:
class Robot extends Model {
...
public function latestLocation() {
$this->hasOne(Location::class, 'robotID', 'locationID')->latest();
}
}
$robots = Robot::whereIn('robots.robotID', [1,2,3,4])
->with('latestLocation')
->get();
然后您可以通过以下方式访问位置:
$robots->first()->latestLocation;