Pull to refresh
32
0
Евгений Бредня @bzq

IT

Send message
Да, можно. И подобное решение уже приводили. В JSON зато можно положить все значения, а не только какое-то одно.
Спасибо за вариант, он почти работающий. На такую ошибку я уже указывал в комментариях выше, нужно указать ROWS… в определение окна, где sum().
Да хотя бы явно преобразовывать дату в строку по маске, чтобы знать сколько потом откусывать. Тут предложили ещё аналогичный вариант с преобразованием в JSON. Для постгреса так, наверное, даже проще.
Да, такого не было. И почти работает! DISTINCT даёт себя знать, дубликаты строк пропадают. Не знаю, нужны ли они будут или нет, но пропадают… А так красиво, конечно.
Анекдот в тему. Встречаются два девопса. Один другому:
— Мне бы CI и деплой на сервер настроить надо…
— Давай я тебе объясню, как это сделать!
— Объяснить я и сам могу. Мне бы сделать…
Работает. Действительно, можно было обойтись чем-то одним из двух — или оконными функциями, или JOIN-ом. Потому и несколько тяжеловесно.
Так как такое поведение не определено, то и неважно. Главное, чтобы при этом запрос что-то выбирал, а не падал с ошибками.

Вот исходя из того, что с одной датой может быть много строчек, мне больше нравится вариант с ROWS, он будет переключать уровень стоимости на новый при каждой встреченной R-строке. Алгоритмы СУБД часто не перемешивают уже упорядоченные в наборе записи, сохраняя оригинальный порядок, так что цены будут расставлены наиболее ожидаемым образом.
Вот теперь работает.

Разное поведение, потому что разные вещи выражает. OVER w — это запуск оконной функции в окне w, которое можно определить отдельно. А если OVER (w), то это уже выражение, которое может быть задано в том числе с использованием существующего окна w. В документации достаточно хорошо видна разница: postgrespro.ru/docs/postgresql/12/sql-expressions#SYNTAX-WINDOW-FUNCTIONS
А вот так?
(array_agg(start_date) FILTER(WHERE kind = 'R') OVER w)[1]
...
WINDOW
	w AS (PARTITION BY stock_id, prod_id ORDER BY start_date DESC
              ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)

О! Я бы назвал такую реализацию классической. Сперва делаем группы по уровням стоимости, потом оконной функцией вытаскиваем значения.

Но в реализации есть ошибка. Надо или явно указать порядок по kind, чтобы первой строкой по каждой дате всегда была R, или в определении рамки указать явно ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, чтобы s увеличивалась только на R-строках, а не на родственных. По умолчанию используется режим RANGE. Попробуйте запустить запрос с ROWS… и без на таких данных:
(1,1,'2000-01-05','P', 90.0, 0, 0),
(1,1,'2000-01-06','P', 80.0, 0, 0),
(1,1,'2000-01-06','R',120.0,41.22,6.19),
(1,1,'2000-01-07','P', 80.0, 0, 0),

Интересная идея с использованием последовательности, мне такое в голову не приходило. И ведь работает! Из недостатков укажу, что требуются права на создание последовательности.
Супер! Это получается использование FILTER в оконной функции. Для компактности можно ещё определение окна отдельно сделать.
Наверное, к сожалению PostgreSQL так не умеет…
Да, работает. JSON — мощное колдунство. Интересно, на Oracle или MSSQL что-то подобное работать будет?
Работает. Хотя преобразования чисел и дат в строку и обратно — это не очень надёжное допущение, вдруг формат даты в настройках базы изменён — и приплыли.
Да, так поинтереснее будет. Теперь работает верно, причём в расширенной версии условия.
Хитро придумано, но зато в один проход. И ведь работает!
Только другие значения вытаскивать будет тяжеловато, и логику работы тяжело разглядеть.
Можете пояснить, зачем использовали в row_number() over (… start_date ...)? И как собираетесь вытаскивать остальные поля из нужной строчки?

Information

Rating
9,308-th
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity