2012-04-15 30 views
27

私はここでいくつかのトピックを見つけましたが、私は依然としてクエリの正しい設定を見つけることができません。PostgreSQL - GROUP BY句または集計関数で使用される

これは、ローカルホスト上でも、私の作品のクエリ、次のとおりです。

@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の上で私に上記のエラーできます - BY句GROUPのか、集約関数で使用すること。

その後、私は、私は、テーブル内のすべての列を指定する必要があることを、どこかで読んだことがあるので、私はこの試みた:...

@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の上でローカルホスト上で動作してもいないしません。

クエリの正しい設定は何でしょうか?

答えて

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

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

30

(すべてまたはほとんどの行を取得する)このようなクエリはJOIN前にあなたGROUP場合高速です。このように:

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の行は、最初にそれぞれ多くのユーザーに参加することによって乗算してから再度グループ化して、一意になるようにする必要はありません。
右テーブルのみをグループ化する必要があります。これにより、ロジックがさらに簡単になります。

関連する問題