J'ai trouvé quelques sujets ici sur SO, mais je ne trouve toujours pas la bonne configuration pour ma requête.
C'est une requête qui me convient bien sur 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')
Mais sur Heroku me donne l'erreur ci-dessus - clause GROUP BY ou être utilisé dans une fonction d'agrégation.
Ensuite, j'ai lu quelque part que je devrais spécifier toutes les colonnes du tableau, j'ai donc essayé ceci:
@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')
Mais cela ne fonctionne pas sur localhost et pas sur Heroku ...
Quelle devrait être la bonne configuration de la requête?
Je pense que vous essayez de regrouper et de regrouper sur la même colonne. Cela dépend des données que vous souhaitez. Ether fait ceci:
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
Ou vous voulez tout compter peut-être? Alors comme ça:
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
Une requête comme celle-ci (récupération de toutes les lignes ou de la plupart) est plus rapide si vous GROUP
avant JOIN
. Comme ça:
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;
De cette façon, vous avez besoin de beaucoup moins d'opérations de jointure. Et les lignes de la table cars
ne doivent pas d'abord être multipliées en se joignant à de nombreux utilisateurs chacune, puis regroupées pour être à nouveau uniques.
Seul le bon tableau doit être regroupé, ce qui simplifie également la logique.
Vous pouvez utiliser l'astuce MAX()
sur la colonne des voitures.
@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')