Redshift оконная функция для изменения в столбце - PullRequest
0 голосов
/ 11 марта 2019

У меня есть таблица красного смещения, среди прочего, столбец id и plan_type, и я хотел бы получить предложение группы оконных функций, где plan_type изменяется так, что если это данные, например:

| user_id | plan_type | created    |
|---------|-----------|------------|
| 1       | A         | 2019-01-01 |
| 1       | A         | 2019-01-02 |
| 1       | B         | 2019-01-05 |
| 2       | A         | 2019-01-01 |
| 2       | A         | 2-10-01-05 |

Я хотел бы получить такой результат, когда я получу первое свидание о том, что plan_type было "новым":

| user_id | plan_type | created    |
|---------|-----------|------------|
| 1       | A         | 2019-01-01 |
| 1       | B         | 2019-01-05 |
| 2       | A         | 2019-01-01 |

Возможно ли это с оконными функциями?

РЕДАКТИРОВАТЬ

Так как у меня есть некоторый мусор в данных, где plan_type может иногда быть нулевым, и принятое решение не включает первую строку (так как у меня не может быть OR is not null, мне пришлось внести некоторые изменения.Надеюсь, он поможет другим людям, если у них возникнут аналогичные проблемы. Окончательный запрос выглядит следующим образом:

SELECT * FROM
(
 SELECT 
    user_id, 
    plan_type, 
    created_at,
    lag(plan_type) OVER (PARTITION by user_id ORDER BY created_at) as prev_plan,
    row_number() OVER (PARTITION by user_id ORDER BY created_at) as rownum 
 FROM tablename
 WHERE plan_type IS NOT NULL
) userHistory 
WHERE
    userHistory.plan_type <> userHistory.prev_plan
    OR userHistory.rownum = 1
ORDER BY created_at;

plan_type IS NOT NULL отфильтровывает неверные данные в исходной таблице и внешнем выражении where, где вносятся любые изменения ИЛИпервая строка данных, которые не были бы включены в противном случае.

ТАКЖЕ БУДУТ ОСТОРОЖНЫ о метке времени созданного_атека, если вы работаете с полем prev_plan, поскольку это, конечно, даст вам времяе нового значения !!!

Ответы [ 3 ]

1 голос
/ 11 марта 2019

Это проблема пробелов и островков. Я думаю lag() - самый простой подход:

select user_id, plan_type, created
from (select t.*,
             lag(plan_type) over (partition by user_id order by created) as prev_plan_type
      from t
     ) t
where prev_plan_type is null or prev_plan_type <> plan_type;

Предполагается, что типы планов могут возвращаться к другому значению, и вам нужно каждое из них.

Если нет, просто используйте агрегацию:

select user_id, plan_type, min(created)
from t
group by user_id, plan_type;
0 голосов
/ 11 марта 2019

использование lag()

select * from
(
select user_id, plant_type, lag(plan_type) over (partition by user_id order by created) as changes, created
from tablename
)A where plan_type<>changes and changes is not null
0 голосов
/ 11 марта 2019

использование row_number() оконная функция

 select * from
    (select *,row_number()over(partition by user_id,plan_type order by created) rn
    ) a where a.rn=1
...