sql - 用于更改列的红移窗口函数
问题描述
我有一个红移表,其中包含一个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 子句获取任何更改或第一行数据,否则不会包含在内。
如果你在你的领域工作,还要小心 created_at 时间戳,prev_plan
因为它当然会给你新值的时间!!!
解决方案
这是一个差距和孤岛问题。我认为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;
推荐阅读
- javascript - 对这种双重递归的工作方式感到困惑
- reactjs - TypeScript:“JSX.IntrinsicElements”类型上不存在属性“图标”
- python - 为什么我的程序不使用指定的代理
- java - 为什么我不能将带有 RestTemplate 的文件发送或 POST 到服务器?
- postman - 在 Postman 中发送请求之前将字段设置为随机数
- powerbi - DAX: Return distinct column values based on other conditions
- javascript - Laravel 在刀片中运行 JavaScript
- r - 在表格中排列显微图像以供发布
- java - 指定的项目文件已经存在?无法导入 Android Studio?
- ios - 如何快速绕过我的应用程序窗口的角落?