根据另一列中的更改创建带有时间戳的最后修改列
Posted
技术标签:
【中文标题】根据另一列中的更改创建带有时间戳的最后修改列【英文标题】:Create last modified column with timestamp based on change in another column 【发布时间】:2020-10-21 09:48:05 【问题描述】:我试图添加一个新列,该列指示另一列的最后修改日期。就我而言,我的项目在特定时间(例如 5/1/19)以特定状态启动。在某些情况下,项目可能会改变其状态(取消或停止)。每天早上拍摄一张快照,在这种情况下可用于跟踪上次修改日期。
有不同的项目(ID、名称)和不同类型的状态。
目前:
project_ID Name Status Date
1 ABC Cancelled 1/4/20
1 ABC Cancelled 1/3/20
1 ABC Continued 1/2/20
1 ABC Continued 1/1/20
.. ... ......... ......
1 ABC Continued 5/1/19
我想实现下表:
project_ID Name Status Date LastModified
1 ABC Cancelled 1/4/20 1/3/20
1 ABC Cancelled 1/3/20 1/3/20
1 ABC Continued 1/2/20 5/1/19
1 ABC Continued 1/1/20 5/1/19
.. ... ......... ...... ......
1 ABC Continued 5/1/19 5/1/19
【问题讨论】:
提供你的表的样本数据 ***.com/questions/43570037/… 【参考方案1】:这是一种间隙和孤岛问题,您要确定每个孤岛的起点。您每天有一条记录这一事实稍微简化了解决方案:我会使用 row_number()
和日期算术来定义相邻记录组,然后使用窗口最小值来获取每个组的第一个日期。
select t.*,
min(date) over(partition by project_id, status, date - rn * interval '1 day') last_modified
from (
select t.*, row_number() over(partition by project_id, status order by date) rn
from mytable t
) t
order by project_id, date
Demo on DB Fiddle
【讨论】:
【参考方案2】:您也可以使用 lag()
和累积最大值来解决此问题:
select t.*,
max(date) filter (where prev_status is distinct from status) over (partition by project_id, name order by date) as last_change_date
from (select t.*,
lag(status) over (partition by project_id, name order by date) as prev_status
from t
) t;
子查询计算先前的状态,以识别任何更改。然后,外部查询取检测到状态变化的日期的最大值。
这种方法的一个优点(或者可能是弱点?)是,如果缺少任何快照日期,它是稳健的。任何此类差距都会被忽略。
【讨论】:
【参考方案3】:我能够通过使用@Philipp Johannis 建议的查询来解决问题。
这里我使用了 MIN 而不是 MAX:
SELECT project_id,
status,
date,
MIN(date)OVER(PARTITION BY project_id, status) AS LastModified
FROM TableABC
ORDER BY date DESC
我无法让其他两个答案正常运行,而且这个解决方案似乎更容易阅读和理解,这就是为什么我将把这个作为解决方案突出显示。
【讨论】:
以上是关于根据另一列中的更改创建带有时间戳的最后修改列的主要内容,如果未能解决你的问题,请参考以下文章
如何根据 PySpark 数据框的另一列中的值修改列? F.当边缘情况