PostgreSQL - GROUP BY子句或用于聚合函数

use*_*621 29 sql postgresql heroku ruby-on-rails-3

我在SO上找到了一些主题,但我仍然无法找到正确的查询设置.

这是查询,在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')
Run Code Online (Sandbox Code Playgroud)

但是在Heroku上给出了上面的错误 - GROUP BY子句或者在聚合函数中使用.

然后我在某处读过,我应该指定表中的所有列,所以我尝试了这个:

@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')
Run Code Online (Sandbox Code Playgroud)

但这不适用于localhost,也不适用于Heroku ......

什么应该是正确的查询配置?

Erw*_*ter 32

如果您在此之前,诸如此类的查询(检索所有或大多数行)会更快.像这样:GROUPJOIN

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;
Run Code Online (Sandbox Code Playgroud)

这样,您需要更少的连接操作.并且表的行cars不必首先通过连接到每个用户然后再分组为唯一.
只有正确的表必须进行分组,这也使逻辑更简单.


Ari*_*ion 28

我想你正试图在同一列上汇总和分组.这取决于您想要的数据.以太这样做:

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
Run Code Online (Sandbox Code Playgroud)

或者你想算所有可能?然后像这样:

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
Run Code Online (Sandbox Code Playgroud)


use*_*207 7

你可以MAX()在汽车专栏上使用技巧.

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