Выберите данные с количеством в Postgresql - PullRequest
0 голосов
/ 22 января 2020

Я хочу спросить, как выбрать данные вместе с данными подсчета.

В этом случае я хочу, чтобы появился пользователь и количество транзакций, которые у него есть.

Вот так код, который я сделал.

SELECT "transaction"."user_id",
COUNT(transaction.id) trans_count
FROM transaction 
inner join "users" on "users"."id" = "transaction"."user_id"
GROUP BY user_id

Код выше успешно выбирает user_id и trans_count, но когда я пытаюсь показать users.name

, появляется это сообщение об ошибке.

Ошибка в запросе: ОШИБКА: столбец "users.name" должен появляться в предложении GROUP BY или использоваться в статистической функции LINE 3: "users". "Name"

Правда ли, что я не могу выбрать другие данные при подсчете данных или есть лучший способ?.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 22 января 2020

Когда вы используете GROUP BY Вы должны быть сгруппированы по всем извлекаемым столбцам или использовать агрегированные функции

Группировать по (так же, как @rohitvats)

GROUP BY "transaction"."user_id", "user"."name"

--- - ИЛИ ----

Агрегатные функции MAX(), MIN()

SELECT "transaction"."user_id",
MAX("user"."name") as name,
COUNT(transaction.id) trans_count
FROM transaction 
inner join "users" on "users"."id" = "transaction"."user_id"
GROUP BY "transaction"."user_id"
0 голосов
/ 22 января 2020

Ваш код будет работать , если вы агрегируете по users.id:

SELECT u.id, u.user_name, COUNT(*) as trans_count
FROM users u JOIN
     transaction t
     ON t.id = u.user_id
GROUP BY u.id;

(я удалил двойные кавычки, потому что они загромождают логи c и не нужны для объясните, что происходит.)

Почему? Предположительно, users.id является уникальным (или эквивалентно первичным ключом). Postgres поддерживает агрегирование по уникальному ключу в таблице, а также включение неагрегированных столбцов в SELECT. Это реализация «функционально зависимых» агрегатов из стандарта SQL.

Когда вы используете transactions.user_id, Postgres не распознает функциональную зависимость (даже если вы думаете, что ON пункт будет подразумевать это). Итак, ваш код не работает.

Альтернативой является добавление user_name к GROUP BY. Однако ваша версия почти работает, если вы используете столбец из правильной таблицы.

0 голосов
/ 22 января 2020

Вы можете включить user.name в group by:

SELECT "transaction"."user_id",
"user"."name",
COUNT(transaction.id) trans_count
FROM transaction 
inner join "users" on "users"."id" = "transaction"."user_id"
GROUP BY "transaction"."user_id", "user"."name"

В противном случае, когда СУБД пытается объединить (group) несколько строк в одну строку, она не знает, какая Значение name должно быть выбрано, поэтому выдает ошибку.

В этом случае user_id и user.name имеют отображение один-к-одному, поэтому вы можете просто включить name в предложение group by.

В противном случае вы ' я должен сказать СУБД, как выбрать одно значение из нескольких записей в каждой группе, например:

min(user.name) или max(user.name)

SELECT "transaction"."user_id",
min("user"."name") user_name,
COUNT(transaction.id) trans_count
FROM transaction 
inner join "users" on "users"."id" = "transaction"."user_id"
GROUP BY "transaction"."user_id"
...