【问题标题】:Left join to get a single row in Laravel左连接以获得 Laravel 中的单行
【发布时间】:2015-02-03 16:51:06
【问题描述】:

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

这是我的代码:

$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();

这些 cmets 是我的几个尝试中的一些......

我想只从照片表中获取一条记录,该记录与首先更新且状态为 1 的外键 album_id 匹配

请帮忙...

【问题讨论】:

  • 在两行注释前添加$query->take(1); 有帮助吗?
  • Call to undefined method lluminate\Database\Query\JoinClause::take() 错误@NorthBridge

标签: php sql laravel-4 eloquent query-builder


【解决方案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();

【讨论】:

    【解决方案2】:

    我使用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的执行时间,我还是像我上面的sn-p一样

    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 但两者都做了同样的事情......

    【讨论】:

      【解决方案3】:

      您可以使用leftJoinrightJoin 来实现它(但后者会返回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();
      

      【讨论】:

      • 欢迎好友@JarekTkaczyk,在您发布此 +1 之前,我做了同样的事情,但略有不同
      • @Ronser 你有答案,它是正确的。如果这不是您想要达到的目标,请改写问题并准确说出您期望的结果,然后告诉我。
      • 老兄,你为我节省了很多时间!谢谢哥们。我问了类似的问题,但没有得到有效的答案。这里stackoverflow.com/questions/32676622/conditional-table-joins
      【解决方案4】:

      您是否要检查状态为“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() 将返回一个数组。

      【讨论】:

      • 我需要一张包含一张照片的所有专辑列表
      • 相册::->哪里错了,纠正相册::哪里
      猜你喜欢
      • 2019-09-10
      • 2016-07-11
      • 2012-04-19
      • 2018-03-06
      • 2017-05-18
      • 2018-08-08
      • 2018-02-14
      • 2017-12-09
      • 1970-01-01
      相关资源
      最近更新 更多