获取基于另一列的条件成立的每一行的最新记录(Hive SQL)
Posted
技术标签:
【中文标题】获取基于另一列的条件成立的每一行的最新记录(Hive SQL)【英文标题】:Getting most recent record for each row where a condition based on another column holds (Hive SQL) 【发布时间】:2021-10-27 17:58:52 【问题描述】:抱歉,如果这是一个重复的问题,但我无法找到直接回答我问题的内容。我有一个看起来像这样的表:
Person | Date | In-office
-------------------------------
1 | 01-01-2021 | 0
1 | 01-02-2021 | 1
1 | 01-04-2021 | 0
1 | 01-08-2021 | 1
2 | 01-02-2021 | 1
2 | 01-05-2021 | 0
2 | 01-09-2021 | 0
3 | 01-01-2021 | 0
3 | 01-02-2021 | 1
3 | 01-06-2021 | 0
3 | 01-09-2021 | 1
我想为每一行添加第四列,其中包含该人员在办公室的最近日期该行中的日期之前:
Person | Date | In-office | Most recent in-office
-------------------------------------------------------
1 | 01-01-2021 | 0 | Null
1 | 01-02-2021 | 1 | Null
1 | 01-04-2021 | 0 | 01-02-2021
1 | 01-08-2021 | 1 | 01-02-2021
2 | 01-02-2021 | 1 | Null
2 | 01-05-2021 | 0 | 01-02-2021
2 | 01-09-2021 | 0 | 01-02-2021
3 | 01-01-2021 | 0 | Null
3 | 01-02-2021 | 1 | Null
3 | 01-06-2021 | 1 | 01-02-2021
3 | 01-09-2021 | 1 | 01-06-2021
在 Hive 中是否有一种简单的方法可以做到这一点?我还没有找到一种方法来使用窗口函数/分区来做到这一点。原则上,在person
上将表连接到自身并应用一些合理的过滤器和聚合应该可以工作,但我的实际数据大约有数千万行,实际上考虑到我的资源限制,这并不可行。
任何帮助将不胜感激!
【问题讨论】:
【参考方案1】:您可以尝试使用MAX
窗口函数并使用 (RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
) 将边界限制为前行。通过在 case 表达式 (CASE WHEN in_office=1 THEN cdate END
) 中根据此人是否在职过滤日期,并使用 over 子句的顺序 (ORDER BY date
) 和范围,我们可以检索该人的最长在职日期,例如
select
*,
MAX(CASE WHEN in_office=1 THEN date END) OVER (
PARTITION BY person
ORDER BY date
RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
) as most_recent_in_office
from sample_data
【讨论】:
感谢您的建议!我没有想过在 MAX 窗口函数中使用 CASE WHEN。我会试一试,如果它有效,我会报告:) 感谢您的建议——这似乎对我的用例有用! @user3447259 太好了。请投票并标记为已接受的答案,以便其他有类似问题的 *** 访问者能够确定该答案可用于解决他们的问题/问题。以上是关于获取基于另一列的条件成立的每一行的最新记录(Hive SQL)的主要内容,如果未能解决你的问题,请参考以下文章