Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mysql Query Group Concat Limit multiple record of child table in single query

Album Table:

+------------------------------+
| id      name       updated_at|
+------------------------------+

Album_member Table:

+------------------------------------+
| id      album_id         member_id |
+------------------------------------+

Album_media Table:

+--------------------------------+
| id       album_id         link |
+--------------------------------+

My Query:

$limit = 30;
$member_id = 1;
SELECT a . *,
(SELECT GROUP_CONCAT(CONCAT('$assets/album_image/medium/', ds_album_media.link) SEPARATOR ',') as link
FROM ds_album_media WHERE ds_album_media.album_id = a.id ORDER BY a.updated_at desc LIMIT 0 , 5)
AS photo_link FROM `ds_album` a
LEFT JOIN ds_album_media amd ON amd.album_id = a.id
LEFT JOIN ds_album_member amb ON amb.album_id = a.id
where amb.member_id = " . $member_id . " GROUP BY a.id
ORDER BY a.updated_at desc LIMIT 0 , $limit

Now for each album there is multiple album_media and album_member is for which album user is following i want data in such a way that retrieve all album that use follows and all photos of that album but constrains is that need to set album_media limit 5 and album limit 30.

  1. limit not working as i have used group_concat any other way to limit the records of group_concat?

  2. I am using laravel so any solution regarding that is also most welcome.

I have used substring_index() function but is it sufficient way in perspective of performance?

I have tried this query with laravel,

Laravel Query(Edit):

$data = Album::select("album.*")
    ->leftjoin("album_media", 'album_media.album_id', '=', 'album.id')
                    ->leftjoin("album_member", 'album_member.album_id', '=', 'album.id')
    ->where('album_member.member_id', $member_id)
    ->with(['albumMedia' => function($query) {
       return $query->where('album_id','album.id')->take(5);
    }])
    ->groupBy('album.id')->orderBy('album.updated_at', 'desc')->take($limit)->skip($skip)->get()->toArray();
like image 276
Sagar Naliyapara Avatar asked Dec 04 '15 08:12

Sagar Naliyapara


1 Answers

Set up your relationships and then constrain them like so:

$albums = Album::with('albumMedia', 'albumMembers')
->whereHas('albumMembers', function($query) use ($userId) {
    $query->where('albumMembers.member_id', $userId);
})
->orderBy('album.updated_at')
->take($limit)
->skip($skip)
->get();

Lastly, you could then add a method to the Album model which will help you retrieve your concatenated string/link, based on the eagerly-loaded relationship.

Better yet, instead of doing a whereHas, you could so something like a scope method on the Album model which will create it for you. This would be much cleaner than the example above.

like image 140
Oddman Avatar answered Oct 16 '22 18:10

Oddman