Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PostgreSQL - GROUP BY clause or be used in an aggregate function

I found some topics here on SO, but I still can't find the right setup for my query.

This is query, that works me well on localhost:

@cars = Car.find_by_sql('SELECT cars.*, COUNT(cars.id) AS counter                           FROM cars                           LEFT JOIN users ON cars.id=users.car_id                           GROUP BY cars.id ORDER BY counter DESC') 

But on Heroku gives me the error above - GROUP BY clause or be used in an aggregate function.

Then I have read somewhere, that I should specify all columns in the table, so I tried this:

@cars = Car.find_by_sql('SELECT cars.id, cars.name, cars.created_at,                                  cars.updated_at, COUNT(cars.id) AS counter                           FROM cars                           LEFT JOIN users ON cars.id=users.car_id                           GROUP BY (cars.id, cars.name, cars.created_at, cars.updated_at)                           ORDER BY counter DESC') 

But this doesn't work on localhost and also not on Heroku...

What should be the right config of the query?

like image 902
user984621 Avatar asked Apr 15 '12 11:04

user984621


People also ask

Can GROUP BY be used with aggregate functions?

The GROUP BY statement is often used with aggregate functions ( COUNT() , MAX() , MIN() , SUM() , AVG() ) to group the result-set by one or more columns.

Which clause can be used with aggregate functions?

An aggregate function can be used in a WHERE clause only if that clause is part of a subquery of a HAVING clause and the column name specified in the expression is a correlated reference to a group. If the expression includes more than one column name, each column name must be a correlated reference to the same group.

Can we use aggregate function without GROUP BY clause?

While all aggregate functions could be used without the GROUP BY clause, the whole point is to use the GROUP BY clause. That clause serves as the place where you'll define the condition on how to create a group. When the group is created, you'll calculate aggregated values.

Which clause Cannot be used with aggregate functions?

Key Differences between WHERE and HAVING Clause We cannot use the WHERE clause with aggregate functions because it works for filtering individual rows. In contrast, HAVING can works with aggregate functions because it is used to filter groups.


2 Answers

A query such as this (retrieving all or most rows) is faster if you GROUP before you JOIN. Like this:

SELECT id, name, created_at, updated_at, u.ct FROM   cars c LEFT   JOIN (     SELECT car_id, count(*) AS ct     FROM   users     GROUP  BY 1     ) u ON u.car_id  = c.id ORDER  BY u.ct DESC; 

This way you need far fewer join operations. And the rows of the table cars do not have to be first multiplied by joining to many users each and then grouped back to be unique again.
Only the right table has to be grouped, which makes the logic simpler, too.

like image 153
Erwin Brandstetter Avatar answered Sep 20 '22 14:09

Erwin Brandstetter


I think you are trying to aggregate and group by on the same column. It depends on what data you want. Ether do this:

SELECT   cars.name,   cars.created_at,   cars.updated_at,   COUNT(cars.id) AS counter  FROM cars  LEFT JOIN users    ON cars.id=users.car_id  GROUP BY cars.name, cars.created_at, cars.updated_at  ORDER BY counter DESC 

Or you want to count all maybe? Then like this:

SELECT  cars.id,  cars.name,   cars.created_at,   cars.updated_at,   COUNT(*) AS counter  FROM cars  LEFT JOIN users    ON cars.id=users.car_id  GROUP BY cars.id, cars.name, cars.created_at, cars.updated_at  ORDER BY counter DESC 
like image 28
Arion Avatar answered Sep 18 '22 14:09

Arion