Software Development

What is the correct Eloquent syntax to perform a "SELECT COUNT(*) GROUP BY" query?

MA Asked by Marcus Thorne · 04-02-2025
0 upvotes 14,272 views 0 comments
The question

I am trying to generate a report in Laravel that counts the number of users per city. In raw SQL, I would simply run SELECT city, COUNT(*) as total FROM users GROUP BY city. However, when I try to translate this into Eloquent, I’m unsure how to include the count aggregate alongside the group by clause without resorting to a completely raw query. Should I be using DB::raw within a select() method, or is there a more "Eloquent-way" to handle grouping and counting simultaneously?

3 answers

0
DR
Answered on 05-02-2025

To achieve this in Eloquent, the most common and efficient approach is to use the selectRaw() method. This allows you to include the SQL aggregate function while still returning a collection of Eloquent models (or generic objects).

The syntax would look like this: $results = User::selectRaw('city, count(*) as total')->groupBy('city')->get();

This generates the exact SQL you’re looking for. Once executed, you can access the count just like any other property on your model: $results->first()->total. It’s important to remember that if your config/database.php has strict mode set to true (which is the default), you must include every column mentioned in your select inside the groupBy clause to avoid SQL syntax errors.

0
SA
Answered on 06-02-2025

That works perfectly for getting the data, but what if I want to sort the results so that the cities with the highest number of users appear first? Do I just chain an orderBy at the end, and can I reference the "total" alias I created in the selectRaw?

MA 07-02-2025

Sarah, yes you can! You can simply append ->orderBy('total', 'desc') to the query. Laravel is smart enough to recognize the alias you defined in your raw select. If you find yourself doing this often for complex reporting, you might also look into using orderByRaw('count(*) DESC') if you prefer not to rely on aliases

0
AL
Answered on 08-02-2025

If you don't want to use selectRaw, you can also use the DB facade directly: DB::table('users')->select('city', DB::raw('count(*) as total'))->groupBy('city')->get();. It’s essentially the same result, but sometimes cleaner if you aren't using any model-specific logic.

DR 09-02-2025

I agree with Alex, but I usually stick to the Model approach (Answer 1) because it allows me to use Eloquent features like "Accessors" or "Appended attributes" on the results later on. It keeps the code feeling more "Laravel-like."

Share your thoughts

Your email address will not be published. Required fields are marked (*)

Professional Counselling Session

Still have questions?
Schedule a free counselling session

Our experts are ready to help you with any questions about courses, admissions, or career paths. Get personalized guidance from industry professionals.

Request a Call Back

Search Online

We Accept

We Accept

Follow Us

"PMI®", "PMBOK®", "PMP®", "CAPM®" and "PMI-ACP®" are registered marks of the Project Management Institute, Inc. | "CSM", "CST" are Registered Trade Marks of The Scrum Alliance, USA. | COBIT® is a trademark of ISACA® registered in the United States and other countries.

Book Free Session