2012-04-15 93 views
27

我在這裏找到了一些關於SO的話題,但我仍然找不到適合我的查詢的正確設置。PostgreSQL - GROUP BY子句或在聚合函數中使用

這是查詢的作品我很好在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') 

但在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') 

但這並不在localhost在Heroku上工作,也沒有...

什麼應該是查詢的正確配置?

回答

26

我認爲你正在嘗試在同一列進行聚合和分組。這取決於你想要的數據。以太做這個:

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 

或者你想數一切都可能?然後像這樣:

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 
+0

謝謝,真的有助於明確此操作。 – edencorbin 2017-03-04 23:54:53

5

您可以使用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') 
+0

任何想法,如果使用像這樣的max可能會導致性能問題? – achabacha322 2017-09-15 19:24:24

30

的查詢,如下所示(檢索所有或大部分行)是更快如果你GROUP之前JOIN。像這樣:

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; 

這樣你就不需要連接操作了。並且表cars的行不必先乘以每個加入許多用戶然後再分組以再次唯一。
只有正確的表格必須分組,這也使得邏輯更簡單。

相關問題