繁体   English   中英

Laravel leftJoin 只加入右表的最后一条记录

[英]Laravel leftJoin only last record of right table

我是 laravel 的新用户。

我有两张桌子。 1) 产品 2) 价格

-----------------------------
- products                  -
-----------------------------
- id_product | int (p_key)  -
- name       | varchar      -
-----------------------------

-------------------------
- prices                -
-----------------------------
- id_price   | int (p_key)  -
- id_product | int          -
- price      | int          -
-----------------------------

products表包含有关产品的数据,例如idname ……价格变化存储在prices表中,其中最后一条记录是应向用户显示的最新价格。

现在我想搜索products并从prices表中获取每种产品的最新价格。 这是我的查询:

$result = DB::table('products')->leftJoin('prices', function($join) {
    $join->on('products.id_product', '=', 'prices.id_product');
})->whereRaw(MY_SEARCH_FILTERS);

上面的代码是错误的,因为如果一个产品在prices表中有 4 条记录,那么它将在$result中重复 4 次,但应该只显示最后一个价格的 1 条记录。

这里我们有 2 个表用户答案,其中用户是左表,答案是右表,其中包含用户答案。

我们想给加入的用户留下答案,但加入应该是最新的记录或答案表。

$query = Users::select('users.id', 'users.user_name','answers.created_at as last_activity_date')
->leftJoin('answers', function($query) 
{
   $query->on('users.id','=','answers.user_id')
   ->whereRaw('answers.id IN (select MAX(a2.id) from answers as a2 join users as u2 on u2.id = a2.user_id group by u2.id)');
})
->where('users.role_type_id', Users::STUDENT_ROLE_TYPE)->get();

你可以使用 Laravel Elquent 让它变得简单:

class Product extends Model
{
   public function lastPrice()
    {
        // optional: change id_price  to created_at by add created_at to prices table 
        return $this->hasOne(Price::class)->orderBy('id_price', 'DESC');
    }

}

现在在

public function getProducts(){
 $MY_SEARCH_FILTERS=....;
 // get all products with last price 
 $products=Product::with('lastPrice')->whereRaw(MY_SEARCH_FILTERS)->get()  
 return   $products
}

你需要在这里添加两件事,

1) orderBy 降序价格表。

2) DB::table 函数中的第一个子句(它将仅获取 1 条记录,即最新价格)。

解决方案:

$result = DB::table('products')
->leftJoin('prices',function($join)
                    {
                      $join->on('products.id_product', '=',  'prices.id_product')
                    })->whereRaw(MY_SEARCH_FILTERS)
->orderBy('prices.id_price','desc')
->first();

您还可以使用 (Laravel 5.1) :

$result = DB::table('products')
          ->leftJoin('products.id','=','prices.id_product')
          ->whereRaw(MY_SEARCH_FILTERS)
          ->orderBy('prices.id_price','desc')
          ->first();

这里我们有 2 个表“ articles ”和“ comments ”,其中articles是左表, comments是右表,其中包含文章的评论。

我们想留下带有comments连接articles ,但连接应该是comments表中的最新记录。

$query = Article::select('articles.*', 'comments.comment as article_comment')
->leftJoin('comments', function($query) {
    $query->on('comments.article_id','=','articles.id')
        ->whereRaw('comments.id IN (select MAX(a2.id) from comments as a2 join articles as u2 on u2.id = a2.article_id group by u2.id)');
})
->get();

我从这里找到了这个解决方案https://laravelcode.com/post/how-to-get-last-record-from-leftjoin-table-in-laravel

您也可以使用Raw queries<\/code>来做到这一点

DB::table('articles')
->select('articles.*, 
(select comments.* from comments where comments.article_id = articles.id 
order by comments.created_at desc limit 1))
->get();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM