Левое соединение, чтобы получить одну строку в Laravel

я безуспешно пытался 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

помощь pls...

4 ответов


я использовал 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 ' s

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 но оба сделали то же самое...


вы можете добиться этого, используя либо 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'? Если это так, то у вас отсутствует знак равенства из вашего окончательного где.

попробуй:

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

в качестве альтернативы вы можете достичь этого с помощью " on "вместо" where " внутри функции join. Вам также не нужно разделять запрос внутри функции и делать это как одну строку с помощью' ->':

$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 () вернет массив.


в качестве прямого ответа, который приводит к одному объекту, я предлагаю следующий запрос:

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