使用Hive SQL为分组记录添加每日累计计数列
解决Hive中按品类生成日期累计计数的问题
没问题,这需求用Hive的窗口函数就能轻松搞定!我分两种场景给你写SQL,覆盖不同的数据源情况:
场景1:原始数据是扁平化的空格分隔字符串
假设你的原始数据存在一张叫raw_fruit_records的表中,有一个字段raw_content存储你提供的那串空格分隔内容,用下面的SQL就能把它转换成结构化数据并生成累计计数:
WITH structured_data AS ( -- 第一步:把扁平化字符串拆成每行一条fruit+day的结构化数据 SELECT val AS fruit, -- 取当前元素的下一个元素作为对应的日期 lead(val) OVER (ORDER BY pos) AS day FROM raw_fruit_records -- 将字符串拆分为数组,展开每个元素的位置和值 LATERAL VIEW posexplode(split(raw_content, ' ')) exploded AS pos, val -- 跳过开头的"fruit""day"列名,只处理成对的记录 WHERE pos >= 2 AND pos % 2 = 0 ), counted_data AS ( -- 第二步:按品类分组,按日期排序生成累计计数 SELECT fruit, day, -- 行号就是累计计数,因为每日递增1条 ROW_NUMBER() OVER ( PARTITION BY fruit ORDER BY to_date(day, 'MM/dd/yyyy') -- 转日期类型避免字符串排序坑 ) AS count FROM structured_data ) -- 输出最终结果,按品类和日期排序 SELECT fruit, day, count FROM counted_data ORDER BY fruit, day;
场景2:原始数据已经是结构化表
如果你的数据本来就是规整的表(比如表名fruit_daily_records,有fruit和day两个字段),那SQL会更简洁:
SELECT fruit, day, ROW_NUMBER() OVER ( PARTITION BY fruit ORDER BY to_date(day, 'MM/dd/yyyy') ) AS count FROM fruit_daily_records ORDER BY fruit, day;
小提示:
- 用
ROW_NUMBER()是因为你要求每日递增1条,每个品类下按日期排序后的行号正好对应累计计数。 - 加上
to_date(day, 'MM/dd/yyyy')是为了避免字符串排序的错误(比如"1/10/1990"字符串排序会排在"1/2/1990"前面,转成日期类型就会按真实日期顺序排序)。
内容的提问来源于stack exchange,提问作者jumpman8947
相关产品推荐
相关产品推荐

