Ваша проблема в том, что у вас нет столбца, в котором указан правильный порядок.В рамке окна row_number
вы даете order by date
.Но когда в кадре много строк, результат получается совершенно случайным.
Вы должны указать базе данных, что делать со строками в одном кадре.Хотели бы вы взять project_id
?Нет такого индикатора, как «сырой заказ».
Например,
SELECT * FROM table
никогда не дает выделенный порядок (например, порядок вставки наборов данных).Результирующий набор может быть упорядочен совершенно случайно.То же самое для любого окна фрейма, которое вы определяете.
Поэтому вам понадобится способ (столбец или алгоритм), обеспечивающий ожидаемый порядок.
Если вы возьмете ORDER BY date, project_id
тогда (например) кадр для 3/3/18
будет заказан с project_id
12, 15
, который не является вашим "необработанным заказом".Если вы закажете его DESC
, то ваш 1/1/18
кадр будет упорядочен неправильно, потому что первый идентификатор будет 17
.Так что project_id
не является хорошим критерием порядка.Но другой возможности для заказа нет.Это потому, что вам нужен еще один столбец.
Чтобы получить «необработанный заказ», можно использовать столбец идентификатора автоматического увеличения (введите serial
- или в случае Postgres 10 и выше GENERATED AS IDENTITY
-).
Если у вас есть определенный порядок (например, столбец идентификатора вставки), то это может быть ваш запрос:
WITH abc AS (
SELECT insert_id, student_id, project_id, date,
ROW_NUMBER() OVER (PARTITION BY student_id ORDER BY insert_id) rn_asc, -- A
ROW_NUMBER() OVER (PARTITION BY student_id ORDER BY insert_id DESC) rn_desc -- B
FROM projects
)
SELECT
student_id,
MAX(project_id) FILTER (WHERE rn_asc = 1),
MAX(date) FILTER (WHERE rn_asc = 1),
MAX(project_id) FILTER (WHERE rn_asc = 2),
MAX(date) FILTER (WHERE rn_asc = 2),
MAX(project_id) FILTER (WHERE rn_desc = 1),
MAX(date) FILTER (WHERE rn_desc = 1)
FROM abc
GROUP BY student_id
A: Упорядочение кадров студента по возрастанию идентификатора идавая номера строк 1
и 2
, которые помогают отфильтровать первые две строки.
B: упорядочить по убыванию, чтобы получить последнюю строку (которая в данном случае получает row number == 1
)
демо: дБ <> скрипка