I was looking for a solution to a rather related problem: finding the latest entries per group, which is a specialization of the typical largest n-per-group with N = 1.
The solution includes the problem you are working with here (for example, how to build a query in Eloquent), so I am posting it as it may be useful to others. It demonstrates a cleaner way to create a subquery using the powerful Eloquent interface, which has several join columns and where condition is inside the joined sub-select.
In my example, I want to get the latest DNS scan results ( scan_dns table) for each group defined by watch_id . I build the subquery separately.
The SQL I want Eloquent to generate:
SELECT * FROM 'scan_dns' AS 's' INNER JOIN ( SELECT x.watch_id, MAX(x.last_scan_at) as last_scan FROM 'scan_dns' AS 'x' WHERE 'x'.'watch_id' IN (1,2,3,4,5,42) GROUP BY 'x'.'watch_id') AS ss ON 's'.'watch_id' = 'ss'.'watch_id' AND 's'.'last_scan_at' = 'ss'.'last_scan'
I did it as follows:
UPDATE:
Beginning with Laravel 5.6.17 , subquery joins have been added , so there is a custom way to create a query.
$latestPosts = DB::table('posts') ->select('user_id', DB::raw('MAX(created_at) as last_post_created_at')) ->where('is_published', true) ->groupBy('user_id'); $users = DB::table('users') ->joinSub($latestPosts, 'latest_posts', function ($join) { $join->on('users.id', '=', 'latest_posts.user_id'); })->get();
ph4r05 Jun 22 '17 at 21:40 2017-06-22 21:40
source share