With Laravel/Lumen eloquent I can get count relations like this:
User::withCount('views')->get();
this will use SQL
select `users`.*, (select count(*) from `views` where `users`.`id` = `views`.`user_id`) as `views_count` from `users`
and return all models with views_count attribute, great.
But I need these views counted with unique IP column. In this query I could simple replace count(*) with count(DISTINCT ip) like this:
select `users`.*, (select count(DISTINCT ip) from `views` where `users`.`id` = `views`.`user_id`) as `views_count` from `users`
and in phpMyAdmin it returns good results. But how achieve this in Laravel eloquent? I cannot find any way to use custom column for count. I can pass array with query function like this:
User::withCount(['views' => function ($q) { // what there? }])->get();
but now I can pass only where conditions, not use Distinct in any way.
I know I can first get models, and then foreach with distinct and count or groupby but I need to keep this single query, fast and simple. And if I can easy achieve this in raw SQL then I also should do this in Laravel somehow. I can use some custom eloquent method if required because I will use this unique count in many places in applications.
So short question - how to combine withCount and Distinct?
PS I also tried to use distinct or groupBy on on model's relation level (on hasMany) but this does not work.
In simple, the Laravel withCount () is used to count the rows present in the relational model and fetch the amount of associated or related records present in the main object. It can be implemented with many relationships like one-to-one, one to many, many to many, polymorphic relationship, querying relationship, dynamic relationship, and so on.
As mentioned in the previous paragraph, the Laravel statement of DISTINCT is a query that identifies the exact value of the search. It returns the value from the database through the following Eloquent Distinct method:
When you need to could a sub query Laravel provides a useful withCount method that is perfect. Take an example of a user can have records with a hasMany relationship: I have a model called BookingCandidate that links to the user by its filled_by_id that matches a user_id
In this query I could simple replace count (*) with count (DISTINCT ip) like this: select `users`.*, (select count (DISTINCT ip) from `views` where `users`.`id` = `views`.`user_id`) as `views_count` from `users`
User::withCount('views', function($query) {
$query->select(DB::raw('count(distinct(ip))'));
})->get();
Solution for Laravel 8.x
User::withCount(['views as views_count' => function($query) {
$query->select(DB::raw('count(distinct(ip))'));
}])->get();
Note: Do not use selectRaw
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With