Оконная функция PostgreSQL: row_number() over (порядок столбцов разделов по col2)

Следующий набор результатов получен из SQL-запроса с несколькими соединениями и объединением. SQL-запрос уже группирует строки по дате и игре. Мне нужен столбец для описания количества попыток игры, разделенных по столбцу даты.

Username   Game     ID   Date

johndoe1   Game_1   100  7/22/14 1:52 AM
johndoe1   Game_1   100  7/22/14 1:52 AM
johndoe1   Game_1   100  7/22/14 1:52 AM
johndoe1   Game_1   100  7/22/14 1:52 AM
johndoe1   Game_1   121  7/22/14 1:56 AM
johndoe1   Game_1   121  7/22/14 1:56 AM
johndoe1   Game_1   121  7/22/14 1:56 AM
johndoe1   Game_1   121  7/22/14 1:56 AM
johndoe1   Game_1   121  7/22/14 1:56 AM
johndoe1   Game_1   130  7/22/14 1:59 AM
johndoe1   Game_1   130  7/22/14 1:59 AM
johndoe1   Game_1   130  7/22/14 1:59 AM
johndoe1   Game_1   130  7/22/14 1:59 AM
johndoe1   Game_1   130  7/22/14 1:59 AM
johndoe1   Game_1   200  7/22/14 2:54 AM
johndoe1   Game_1   200  7/22/14 2:54 AM
johndoe1   Game_1   200  7/22/14 2:54 AM
johndoe1   Game_1   200  7/22/14 2:54 AM
johndoe1   Game_1   210  7/22/14 3:54 AM
johndoe1   Game_1   210  7/22/14 3:54 AM
johndoe1   Game_1   210  7/22/14 3:54 AM
johndoe1   Game_1   210  7/22/14 3:54 AM

У меня есть следующий SQL-запрос, который перечисляет строки в разделе, но не совсем правильно, так как я хочу подсчитать количество экземпляров этой игры на основе даты и игры. В этом случае johndoe1 пять раз пытался сыграть в Game_1, разделенных по отметкам времени.

Этот запрос возвращает набор результатов ниже

select *
, row_number() over (partition by ct."date" order by ct."date") as "Attempts"
from csv_temp as ct

Username   Game     ID   Date             Attempts  (Desired Attempts col.)

johndoe1   Game_1   100  7/22/14 1:52 AM  1          1
johndoe1   Game_1   100  7/22/14 1:52 AM  2          1
johndoe1   Game_1   100  7/22/14 1:52 AM  3          1
johndoe1   Game_1   100  7/22/14 1:52 AM  4          1
johndoe1   Game_1   121  7/22/14 1:56 AM  1          2
johndoe1   Game_1   121  7/22/14 1:56 AM  2          2
johndoe1   Game_1   121  7/22/14 1:56 AM  3          2
johndoe1   Game_1   121  7/22/14 1:56 AM  4          2
johndoe1   Game_1   121  7/22/14 1:56 AM  5          2
johndoe1   Game_1   130  7/22/14 1:59 AM  1          3   
johndoe1   Game_1   130  7/22/14 1:59 AM  2          3
johndoe1   Game_1   130  7/22/14 1:59 AM  3          3
johndoe1   Game_1   130  7/22/14 1:59 AM  4          3
johndoe1   Game_1   130  7/22/14 1:59 AM  5          3
johndoe1   Game_1   200  7/22/14 2:54 AM  1          4
johndoe1   Game_1   200  7/22/14 2:54 AM  2          4
johndoe1   Game_1   200  7/22/14 2:54 AM  3          4
johndoe1   Game_1   200  7/22/14 2:54 AM  4          4
johndoe1   Game_1   210  7/22/14 3:54 AM  1          5
johndoe1   Game_1   210  7/22/14 3:54 AM  2          5
johndoe1   Game_1   210  7/22/14 3:54 AM  3          5
johndoe1   Game_1   210  7/22/14 3:54 AM  4          5

Любые указатели будут очень полезны.


person user1951677    schedule 29.08.2014    source источник
comment
Возможно, это поможет java.dzone.com/articles/difference-between-rownumber   -  person Konstantin V. Salikhov    schedule 29.08.2014
comment
Глядя на желаемые результаты, единственное различие между строками в группе (Desired Attempts col.) — это столбец Attempts. Возможно, вы могли бы просто сгруппировать по Username, Game, ID, добавить count(1), чтобы получить количество попыток, и добавить row_number(), чтобы получить (Desired Attempts col.)?   -  person jakubiszon    schedule 29.08.2014


Ответы (1)


Считайте, что partition by аналогичны полям, которые вы бы group by, тогда, когда значения раздела изменяются, оконная функция перезапускается с 1

РЕДАКТИРОВАТЬ, как указано a_horse_with_no_name, для этого нам нужно dense_rank() в отличие от row_number() rank() или dense_rank() повторить присвоенные ему номера. row_number() должно быть другим значением для каждой строки в разделе. Разница между rank() и dense_rank() заключается в том, что последний не «пропускает» числа.

Для вашего запроса попробуйте:

dense_rank() over (partition by Username, Game order by ct."date") as "Attempts"

Между прочим, вы не разделяете и не упорядочиваете одно и то же поле; просто заказать было бы достаточно, если бы это было необходимо. Это не здесь.

person Paul Maxwell    schedule 29.08.2014
comment
Как и в примере, есть только одна комбинация имени пользователя/игры, каждая строка получит другой номер row_number с вашим оператором (row_number() никогда не генерирует повторяющиеся числа). Должно быть dense_rank() over (partition by Username, Game order by ct."date") - person a_horse_with_no_name; 29.08.2014
comment
@a_horse_with_no_name о боже, совершенно верно - я был сосредоточен на разбиении; благодарю вас. - person Paul Maxwell; 29.08.2014
comment
я был недостаточно изобретателен, чтобы представить, что предложение partition by может принимать более одного столбца, а также я неправильно разделил. Спасибо вам обоим! - person user1951677; 29.08.2014
comment
Когда эта функция появилась в postgres? Он относительно новый? - person Justin Thomas; 29.09.2018