用于更改列的 Redshift window 函数

Redshift window function for change in column

我有一个红移 table,除此之外还有一个 idplan_type 列,我想要一个 window 函数组子句,其中 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 |

这可以用 window 函数实现吗?

编辑

因为我在数据中有一些垃圾,其中 plan_type 有时可以为 null 并且接受的解决方案不包括第一行(因为我不能有 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 过滤掉源 table 和外部 where 子句中的任何更改或不会包含的第一行数据的错误数据。

如果您正在处理 prev_plan 字段,请注意 created_at 时间戳,因为它当然会给您新值的时间!!!

使用row_number()window函数

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

这是一个缺口和孤岛问题。我认为 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;

使用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