SOでいくつかのトピックを見つけましたが、クエリに適した設定がまだ見つかりません。
これはクエリであり、ローカルホストでうまく機能します:
@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')
しかし、これはローカルホストでは機能せず、Herokuでも機能しません...
クエリの正しい構成は何ですか?
同じ列で集計およびグループ化しようとしていると思います。必要なデータによって異なります。エーテルはこれを行います:
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
このような(すべてまたはほとんどの行を取得する)クエリは、GROUP
の前にJOIN
を指定するとfasterになります。このような:
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
は、最初に多くのユーザーにそれぞれ参加することによって乗算され、その後再び一意になるようにグループ化される必要はありません。
正しいテーブルのみをグループ化する必要があります。これにより、ロジックも簡単になります。
車の列で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')