Используя Rails, я пытаюсь выполнить команду SQL, чтобы вернуть массив строк, которые содержат максимальное значение для определенного пользователя в день.PostgreSQL Выберите наибольшее значение в течение периода времени
Например:
user_id(integer) | created_at(datetime) | score(integer)
-------------------+--------------------------------+---------------
1 | "2015-07-27 21:35:24" | 100
1 | "2015-07-27 21:35:24" | 123
2 | "2015-07-27 21:35:24" | 101
2 | "2015-07-27 21:35:24" | 122
3 | "2015-07-27 21:35:24" | 103
3 | "2015-07-27 21:35:24" | 115
1 | "2015-07-26 21:35:24" | 116
1 | "2015-07-26 21:35:24" | 151
2 | "2015-07-26 21:35:24" | 122
2 | "2015-07-26 21:35:24" | 134
3 | "2015-07-26 21:35:24" | 123
3 | "2015-07-26 21:35:24" | 111
1 | "2015-07-25 21:35:24" | 129
1 | "2015-07-25 21:35:24" | 152
2 | "2015-07-25 21:35:24" | 120
2 | "2015-07-25 21:35:24" | 109
3 | "2015-07-25 21:35:24" | 142
3 | "2015-07-25 21:35:24" | 131
Ожидаемые результаты:
user_id(integer) | created_at(datetime) | score(integer)
-------------------+--------------------------------+---------------
1 | "2015-07-27 21:35:24" | 123
2 | "2015-07-27 21:35:24" | 122
3 | "2015-07-27 21:35:24" | 115
1 | "2015-07-26 21:35:24" | 151
2 | "2015-07-26 21:35:24" | 134
3 | "2015-07-26 21:35:24" | 123
1 | "2015-07-25 21:35:24" | 152
2 | "2015-07-25 21:35:24" | 120
3 | "2015-07-25 21:35:24" | 142
Я комбинируя различные соединения, having
и другие методы, но безрезультатно. Я не могу заставить его фильтровать результаты. Я немного продвинулся на select
максимальных значениях в день, но затем я не могу отфильтровать нижние на основе user_id
. Мне удалось сделать это с помощью нескольких group_by
и map
в Rails, но он очень медленный, так как он должен повторить итерацию по всему массиву, и поскольку в нем много записей, это может занять некоторое время.
EDIT:
Мое решение было следующим:
all_scores_in_time_period = UserScore
.where("EXTRACT(MONTH FROM created_at) = ?", Date::MONTHNAMES.index(params[:month_control]))
.where("EXTRACT(YEAR FROM created_at) = ?", params[:year_control])
.select("DISTINCT ON(DATE(created_at), user_id) *")
.order("DATE(created_at) desc")
Это первые фильтры по месяц/год, а затем возвращает список пользователей, их наивысший балл для каждого пользователя в день.
'21: 35: 24' на все дни предотвращает тщательное тестирование решений (поскольку он эффективно преобразует временную метку до настоящего времени), пожалуйста, укажите более реальные временные метки времени. – Dzenly
@ Dzenly - Время не было необходимым. Он должен был быть отфильтрован «датой» в любом случае, а не с датами. Я включил время, чтобы попытаться быть более явным, но вы правы - это немного путает основной момент. – Rockster160