some additions
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
-- тестовый набор данных - искать в реальном наборе тягостно
|
||||
drop table if exists siv cascade;
|
||||
create table siv (
|
||||
siv_id int NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
|
||||
line_key varchar(255) NOT NULL,
|
||||
dt_from date NOT NULL,
|
||||
agreement_version int NOT NULL,
|
||||
line_version int NOT NULL,
|
||||
cost int NULL,
|
||||
descr text NULL
|
||||
);
|
||||
insert into siv (line_key,dt_from,agreement_version,line_version,cost)
|
||||
values
|
||||
('line-01', '2025-03-01', 1, 1, 100),
|
||||
('line-01', '2025-04-01', 1, 2, 100), -- сдвиг на месяц позже
|
||||
('line-01', '2025-02-01', 2, 1, 200), -- сдвиг на 2 месяца раньше и увеличение
|
||||
('line-01', '2025-05-01', 3, 1, 250), -- сдвиг на 3 месяца позже и увеличение
|
||||
('line-01', '2025-05-01', 3, 2, 130), -- уменьшение без сдвига
|
||||
('line-01', '2025-06-01', 4, 1, 160) -- сдвиг и увеличение
|
||||
;
|
||||
select s.*, (select )
|
||||
from siv s
|
||||
|
||||
--https://stackoverflow.com/questions/74296984/how-can-i-discard-rows-that-are-out-of-order
|
||||
SELECT *,
|
||||
LEAD(dt_from) OVER (PARTITION BY line_key ORDER BY dt_from) dt_next
|
||||
FROM
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) mn
|
||||
|
||||
FROM siv
|
||||
) t
|
||||
WHERE t.dt_from=t.mn
|
||||
order by siv_id
|
||||
;
|
||||
-- демонстрирует коллизию совпадающих дат
|
||||
-- для совпадающих дат нам просто нужно взять старшую
|
||||
|
||||
SELECT *,
|
||||
(select min(dt_from) from siv i where i.dt_from > t.dt_from AND i.line_key=t.line_key) dt_next
|
||||
FROM
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) mn
|
||||
FROM siv
|
||||
) t
|
||||
WHERE t.dt_from=t.mn -- получаем лесенку, в которой порядок дат соответствует порядку версий
|
||||
order by siv_id
|
||||
;
|
||||
|
||||
SELECT *,
|
||||
LEAD(dt_from) OVER (PARTITION BY line_key ORDER BY dt_from, agreement_version,line_version) dt_next
|
||||
FROM
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) mn
|
||||
|
||||
FROM siv
|
||||
) t
|
||||
WHERE t.dt_from=t.mn
|
||||
order by siv_id
|
||||
;
|
||||
-- в данном случае siv_id=4 имеет нулевой интервал и не будет учтена в расчетах, хотя и даст лишнее чтение
|
||||
-- вместо null мы можем взять верхнюю границу диапазона
|
||||
Reference in New Issue
Block a user