左连接在 Laravel 中获取单行

问题描述 投票:0回答:4

我一直未能成功尝试左连接并获取所需的数据

这是我的代码:

$album = Albums::->where('users_id',$user_id)
           ->leftJoin('photos',function($query){
              $query->on('photos.albums_id','=','albums.id');
              $query->where('photos.status','=',1);     
                //$query->limit(1);
                //$query->min('photos.created_at');
              })
           ->where('albums.status',1)->get();

这些评论是我的一些尝试...

我想从照片表中获取仅一条记录与外键

album_id
匹配,该外键首先更新且状态为1

请帮忙...

php sql laravel-4 eloquent query-builder
4个回答
19
投票

我使用了

DB::raw()
来实现这一目标

$album  =   Albums::select( 'albums.*',
            DB::raw('(select photo from photos where albums_id  =   albums.id  and status = 1 order by id asc limit 1) as photo')  )
            ->where('users_id',$user_id)
            ->where('albums.status',1)->get();

@JarekTkaczyk 的编码类似,并显示了与我需要的相同的结果,因此特别感谢他付出的时间和精力......

但是比较

quires
的执行时间,我仍然保留上面的代码片段

select `albums`.*, (select photo from photos where albums_id    =   albums.id  and status = 1 order by id asc limit 1) as photo from `albums` where `users_id` = '1' and `albums`.`status` = '1'

拿了

520μs - 580μs

和@JarekTkaczyk 的

select `albums`.*, `p`.`photo` from `albums` left join `photos` as `p` on `p`.`albums_id` = `albums`.`id` and `p`.`created_at` = (select min(created_at) from photos where albums_id = p.albums_id) and `p`.`status` = '1' where `users_id` = '1' and `albums`.`status` = '1' group by `albums`.`id`

采取了

640μs  - 750μs
但两者都做了同样的事情......


9
投票

您可以使用

leftJoin
rightJoin
来实现它(但后者会返回
Photo
模型,所以您可能不需要):

Albums::where('users_id', $user_id)
 ->leftJoin('photos as p', function ($q) {
   $q->on('photos.albums_id', '=', 'albums.id')
     ->on('photos.updated_at', '=', 
       DB::raw('(select min(updated_at) from photos where albums_id = p.albums_id)'))
     ->where('photos.status', '=', 1);
 })
 ->where('albums.status', 1)
 ->groupBy('albums.id')
 ->select('albums.*', fields from photos table that you need )
 ->get();

1
投票

作为产生单个对象的简单答案,我建议以下查询:

$album = DB::table('albums')->select('albums.*', 'photos.photo')
    ->join('photos', 'photos.id', '=', 'albums.id')
    ->where('users_id', $user_id)
    ->where('albums.status', 1)
    ->first();

0
投票

您是否正在尝试检查状态为“1”的相册?如果是这种情况,那么您在最后的位置中缺少等号。

尝试:

 ->where('albums.status','=',1)->first();

或者,您可以通过连接函数内的“on”而不是“where”来实现此目的。您也不需要在函数内部拆分查询,并且可以使用“->”将其作为一行来执行:

$album  =   Albums::->where('users_id',$user_id)
                    ->leftJoin('photos',function($query){
                            $query->on('photos.albums_id','=','albums.id')
                            ->on('photos.status','=',1);
                    })
        ->where('albums.status','=',1)->first();

您需要确保使用“first”,因为它将返回第一个结果的单行。 Get() 将返回一个数组。

© www.soinside.com 2019 - 2024. All rights reserved.