我在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')
但是在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 ...
查询的正确配置应该是什么?
答案 0 :(得分:31)
如果您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
的行不必首先通过连接到每个用户,然后再分组为唯一。
只有正确的表必须进行分组,这也使逻辑更简单。
答案 1 :(得分: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
或者你想算一下所有人?然后像这样:
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
答案 2 :(得分: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')