左连接在Laravel中获得一行

时间:2014-12-05 13:42:13

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

我尝试使用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();

评论是我的几个尝试......

我希望只有照片表中的一条记录匹配首先更新的外键album_id以及状态1

请帮忙......

4 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:5)

您可以使用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();

答案 2 :(得分:0)

您是否正在尝试检查状态为“1”的相册?如果是这种情况,您将错过最终位置的等号。

尝试:

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

或者你可以通过'on'而不是join函数中的'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()将返回一个数组。

答案 3 :(得分:0)

作为一个简单的答案导致单个对象我建议以下查询:

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {

    this.Window.AddFlags(WindowManagerFlags.Fullscreen | WindowManagerFlags.TurnScreenOn);
        if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
        {
            var stBarHeight = typeof(FormsAppCompatActivity).GetField("statusBarHeight", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            if (stBarHeight == null)
            {
                stBarHeight = typeof(FormsAppCompatActivity).GetField("_statusBarHeight", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            }
            stBarHeight?.SetValue(this, 0);
        }
        base.OnCreate(bundle);


        global::Xamarin.Forms.Forms.Init(this, bundle);

        LoadApplication(new App());
    }
}