用于更改列的红移窗口函数
Posted
技术标签:
【中文标题】用于更改列的红移窗口函数【英文标题】:Redshift window function for change in column 【发布时间】:2019-03-11 11:32:46 【问题描述】:我有一个红移表,其中包含 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
字段,请注意 created_at 时间戳,因为它当然会为您提供新值的时间!!!
【问题讨论】:
最后日期有误吗? 【参考方案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;
【讨论】:
谢谢,太好了。但是,由于我在数据中有一些垃圾,其中值有时为空,同时我不得不稍微修改 WHERE 条件,但您的整体解决方案正是我所需要的!谢谢!【参考方案2】:使用row_number()
窗口函数
select * from
(select *,row_number()over(partition by user_id,plan_type order by created) rn
) a where a.rn=1
【讨论】:
【参考方案3】:使用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
【讨论】:
以上是关于用于更改列的红移窗口函数的主要内容,如果未能解决你的问题,请参考以下文章