使用 Hive 中的值计算连续的日期范围
Posted
技术标签:
【中文标题】使用 Hive 中的值计算连续的日期范围【英文标题】:Calculating consecutive range of dates with a value in Hive 【发布时间】:2018-04-18 20:47:04 【问题描述】:我想知道是否可以计算一组 Id 的特定值的连续范围并返回每个 Id 的计算值。 给定以下数据:
+----+----------+--------+
| ID | DATE_KEY | CREDIT |
+----+----------+--------+
| 1 | 8091 | 0.9 |
| 1 | 8092 | 20 |
| 1 | 8095 | 0.22 |
| 1 | 8096 | 0.23 |
| 1 | 8098 | 0.23 |
| 2 | 8095 | 12 |
| 2 | 8096 | 18 |
| 2 | 8097 | 3 |
| 2 | 8098 | 0.25 |
+----+----------+--------+
我想要以下输出:
+----+-------------------------------+
| ID | RANGE_DAYS_CREDIT_LESS_THAN_1 |
+----+-------------------------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 1 |
| 2 | 1 |
+----+-------------------------------+
在这种情况下,范围是信用小于 1 的连续天数。如果 date_key 列之间存在间隙,则范围不必采用下一个值,例如 ID 1 中介于 8096 和 8098 之间的日期钥匙。 是否可以使用 Hive 中的窗口函数来做到这一点?
提前致谢!
【问题讨论】:
【参考方案1】:您可以通过将行分类为组的运行总和来执行此操作,每次找到 creditgroup by。
select id,count(*) as range_days_credit_lt_1
from (select t.*
,sum(case when credit<1 then 0 else 1 end) over(partition by id order by date_key) as grp
from tbl t
) t
where credit<1
group by id
【讨论】:
此解决方案的问题在于,它返回的输出与预期不同,即每 连续 天一行,信用小于 1... 在示例中,对于ID 1,这将是行,值为 1, 2, 1【参考方案2】:关键是折叠所有连续序列并计算它们的长度,我努力以一种相对笨拙的方式实现这一点:
with t_test as
(
select num,row_number()over(order by num) as rn
from
(
select explode(array(1,3,4,5,6,9,10,15)) as num
)
)
select length(sign)+1 from
(
select explode(continue_sign) as sign
from
(
select split(concat_ws('',collect_list(if(d>1,'v',d))), 'v') as continue_sign
from
(
select t0.num-t1.num as d from t_test t0
join t_test t1 on t0.rn=t1.rn+1
)
)
)
-
为每个原始 a 获取 seq 中的前一个数字 b;
检查a-b == 1,表示是否存在“gap”,标记为'v';
将所有 a-b 合并为一个字符串,然后使用 'v' 进行拆分,并计算长度。
要取出 ID 列,应该考虑另一个编码 id 的字符串。
【讨论】:
以上是关于使用 Hive 中的值计算连续的日期范围的主要内容,如果未能解决你的问题,请参考以下文章