разрывами
select my_tbl.*,
sum(amount) over (partition by user_id, types order by id) how_calculate
from (values (123654987, 100, 'A', 1, 100),
(123654987, 100, 'B', 2, 100),
(123654987, 60, 'A', 3, 60),
(123654987, 80, 'A', 4, 140),
(123654987, 50, 'B', 5, 50),
(123654987, 75, 'B', 6, 125)
) my_tbl(user_id, amount, types, id, cor_amount);
cor_amount - это сумма которая должна получиться
Или это только через lag бегать туда сюда ?
Спасибо!
> Или это только через lag бегать туда сюда ? Смотря в каком смысле. ;) А так (если я правильно понял) — это же "стандартная" задача gaps-and-islands, т.е.: 1. Находите точки изменения групп (если types = LAG(types) (PARTITION BY user_id ORDER BY id), то это та же группа). 2. Находите номера групп (SUM/COUNT предыдущего этапа). 3. Получаете "кумулятивы" внутри них, т.е. SUM(amount) OVER (PARTITION BY user_id, grp ORDER BY id). И всё, казалось бы...
Спасибо почитаю про gaps-and-island -не слышал про такое. НО проблема не 1. Находите точки изменения групп (если types = LAG(types) (PARTITION BY user_id ORDER BY id), то это та же группа). Я же смогу так только точку изменения найти, а как мне определить группу(колво), их может быть Х Также задачу нужно решить без переменной. Еще конечно почитаю про это гап-остров. Спасибо!
> Я же смогу так только точку изменения найти, а как мне определить групп Я же набросал, как это делать шаг за шагом. Нахождение точек изменения — только первый шаг, см. далее. > Также задачу нужно решить без переменной. В смысле? Хмм... Вам же примерно вот это нужно, я правильно понял? WITH b AS ( SELECT my_tbl.* FROM ( VALUES (123654987, 100, 'A', 1, 100), (123654987, 100, 'B', 2, 100), (123654987, 60, 'A', 3, 60), (123654987, 80, 'A', 4, 140), (123654987, 50, 'B', 5, 50), (123654987, 75, 'B', 6, 125) ) AS my_tbl(user_id, amount, types, id, cor_amount) ), flags AS ( SELECT *, types IS DISTINCT FROM LAG(types) OVER w AS group_change_flag FROM b WINDOW w AS (PARTITION BY user_id ORDER BY id) ) , group_nums AS ( SELECT *, COUNT(*) FILTER (WHERE group_change_flag) OVER w AS grp_num FROM flags WINDOW w AS (PARTITION BY user_id ORDER BY id) ) SELECT *, SUM(amount) OVER wgroup AS calculated_amount FROM group_nums WINDOW wgroup AS (PARTITION BY user_id, grp_num ORDER BY id) ORDER BY user_id, id;
них*ена себе, извините а что это такое SELECT *, types IS DISTINCT FROM LAG(types) OVER w AS group_change_flag хочу почитать, про это И вот это COUNT(*) FILTER (WHERE group_change_flag) это типа как KEEP в ORACLE ? Огромнеешее спасибо, еще буду читать
> а что это такое Ну так это и есть определение точки изменения... или Вы про IS DISTINCT FROM? Это вот тут: https://www.postgresql.org/docs/current/functions-comparison.html#FUNCTIONS-COMPARISON-PRED-TABLE (мне просто показалось, что так будет короче записать в этом примере, чтобы с NULL-ом не разбираться как-то иначе). Если про OVER w — это использование окна, объявленного в WINDOW. > И вот это <skip> это типа как KEEP в ORACLE ? Это типа как фильтрованные агрегаты (здесь использован как оконная функция) из ISO SQL. ;) См. https://www.postgresql.org/docs/current/sql-expressions.html#SYNTAX-AGGREGATES
» или Вы про IS DISTINCT FROM Да вот это первый раз вижу (( Спасибо »Это типа как фильтрованные агрегаты (здесь использован как оконная функция) из ISO SQL. что-то я в этой жизни не доглядел ( Спасибо большое
Обсуждают сегодня