用于更改列的红移窗口函数

Posted

技术标签:

【中文标题】用于更改列的红移窗口函数【英文标题】:Redshift window function for change in column 【发布时间】:2019-03-11 11:32:46 【问题描述】:

我有一个红移表,其中包含 idplan_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

【讨论】:

以上是关于用于更改列的红移窗口函数的主要内容,如果未能解决你的问题,请参考以下文章

如果您更改用户的红移密码,该用户的任何预先存在的连接是不是仍然有效?

Postgres - 如何对窗口函数列的每 x 行求和?

基于另一列的滞后窗口函数

在 MySQL 8 中使用窗口函数获取不同列的计数

MYSQL窗口函数

MYSQL窗口函数