簡體   English   中英

Laravel只加入了最新行

[英]Laravel left join only the most recent row

我正在尋找一種方法(最好使用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();

提前致謝!

我認為您必須對目標使用類似以下查詢的內容:

SELECT l.*, r.name AS robot_name
FROM location l
JOIN (
  SELECT robotID, MAX(date) AS most_recent
  FROM location
  GROUP BY robotID) AS max
ON l.robotID=max.robotID AND l.date=max.most_recent
JOIN robots r ON r.robotID=l.robotID
WHERE r.robotID IN (1, 2, 3, 4)
ORDER BY l.date DESC

groupBy並不是要那樣使用。 分組依據是指為了聚合的目的而創建數據組。 如果按列分組,則所有其他未聚合列的列值是任意的,不一定與其他列匹配,這很不好。 您需要大量修改邏輯才能實現所需的功能,或者可以使用雄辯的關系來獲取具有最新相關位置的機器人作為關系條目。

我會建議后者,因為它在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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM