Соответствующая часть моей схемы базы данных выглядит следующим образом (Ruby на Rails миграции кода, но должны быть легко читать):Проблемы с SQL запроса с использованием SUM
create_table "team_memberships" do |t|
t.integer "team_id"
t.integer "user_id"
end
create_table "users" do |t|
t.integer "id"
t.string "slug"
end
create_table "performance_points" do |t|
t.integer "id"
t.integer "user_id",
t.date "date",
t.integer "points",
t.integer "team_id"
end
Я хочу, чтобы запрос, который возвращает список пользователей, отсортированных по общей сумме очков производительности, которые они получили с определенной даты. Обратите внимание, что один «performance_points» строка не равна одной точке, мы должны подвести «точки»
Запрос я до сих пор выглядит следующим образом:
SELECT u.id, u.slug, SUM(pp.points) AS total
FROM users u
JOIN performance_points pp ON pp.user_id = u.id
JOIN team_memberships tm ON tm.team_id = pp.team_id AND tm.user_id = pp.user_id
WHERE (pp.date > '2015-08-02 13:57:14.042221')
GROUP BY pp.id, u.id
ORDER BY total DESC
LIMIT 50
Первые три результата являются:
"id","slug","total"
32369,"andreas-jensen-9de10dec-0f88-427f-b135-62cebea611c8",245
23752,"kenneth-kjaerstad",95
34179,"marius-mork-rydal",93
Для проверки правильности результатов подсчета очков для каждого пользователя. Однако второй кажется неправильным. Я запустить этот запрос с идентификатором Кеннета:
SELECT SUM(performance_points.points)
FROM performance_points
WHERE performance_points.user_id = 23752
AND (date > '2015-08-02 13:57:14.042221')
я получаю: 84
. Глядя на все точки производительности Kenneth с:
SELECT performance_points.points
FROM performance_points
WHERE performance_points.user_id = 23752
AND (date > '2015-08-02 13:57:14.042221')
Получаем:
-10 + 1 - 2 + 95 действительно 84, так что я не знаю, что происходит с первого запроса. Почему сумма 95?
Я бегу PostgreSQL версии 9.3.5
Все ли строки показателей производительности для одного и того же team_membership? –
В случае с этим пользователем они есть, но это может быть не всегда так. Пользователи могут быть в нескольких командах и получать очки от каждого. –
Просто замените в исходном запросе 'select ...' на 'select *' и удалите 'group by' clause и, я уверен, вы найдете эту проблему. – Abelisto