PostgreSQL выбирает дополнительные столбцы, которые не используются в статистической функции - PullRequest
3 голосов
/ 21 января 2011

Я пытаюсь написать запрос в PostgreSQL, и я немного расстроен, потому что он работает в других движках баз данных. Мне нужно выбрать 5 лучших пользователей из данной таблицы соединений следующим образом:

SELECT users.*, 
       COUNT(deals.id) AS num_deals 
FROM users, deals 
WHERE deals.users_id = users.id 
GROUP BY users.id 
ORDER BY num_deals LIMIT 5;

Мне нужны 5 лучших пользователей. Этот код работает в sqlite, mysql и т. Д., Но PostgreSQL отказывается выбирать дополнительные поля, которые не используются в агрегатных функциях. Я получаю следующую ошибку:

PGError: ERROR:  column "users.id" must appear in the GROUP BY clause or be used in an aggregate function

Как я могу сделать это в PostgreSQL ??

Ответы [ 4 ]

7 голосов
/ 21 января 2011

Вы можете попробовать:

SELECT users.*, a.num_deals FROM users, (
    SELECT deal.id as dealid, COUNT(deals.id) AS num_deals 
    FROM deals 
    GROUP BY deal.id
) a where users.id = a.dealid
ORDER BY a.num_deals DESC
LIMIT 5
2 голосов
/ 31 марта 2012

Еще одно решение, которое работает, это неявное использование всех атрибутов в GROUP BY

Таким образом, следующий запрос будет окончательным

SELECT users.*, 
       COUNT(deals.id) AS num_deals 
FROM users, deals 
WHERE deals.users_id = users.id 
GROUP BY users.id, users.name, users.attrib1, ..., users.attribN
ORDER BY num_deals LIMIT 5;

Если вы используете фреймворк, такой как rails, вы можете легко реализовать это с помощью функции Model.column_names.

2 голосов
/ 24 января 2011

Если предположить, что users.id - это PK, то вы можете либо

дождаться 9.1

группировки по всем полям

использовать агрегат (т.е. max ())на всех полях

0 голосов
/ 28 марта 2016

На всякий случай, если кому-то нужно стандартное решение ANSI-92, и ему не нравится способ объединения таблиц в Oracle…

SELECT users.*, num_deals
FROM users
JOIN
  (SELECT deals.users_id as users_id, count(deals.users_id) as num_deals
   FROM deals
   GROUP BY deals.id) grouped_user_deals
ON grouped_user_deals.users_id = users.id
ORDER BY num_deals DESC
LIMIT 5;
...