Hive表列转行需求:将指定列值转为列名并填充对应值
解决Hive中行转列(Pivot)的需求
嘿,你这个需求就是把长格式的数据转成宽格式,也就是典型的行转列操作,在Hive里有两种靠谱的实现方式,适配不同版本的Hive:
方案1:Hive 2.3.0及以上版本(推荐,语法简洁)
从Hive 2.3.0开始官方支持PIVOT语法,刚好匹配你的需求。假设你的原始表名叫app_data,列分别是id(就是那个带|的字符串)、col2(数值列,0/1)、col3(app名称列),直接用下面的SQL:
SELECT * FROM app_data PIVOT ( -- 因为每个id+app_name唯一,用MAX/MIN都能拿到对应值 MAX(col2) FOR col3 IN ( 'app_3' AS app_3, 'app_9' AS app_9, 'app_18' AS app_18, 'app_2' AS app_2, 'app_12' AS app_12, 'app_other' AS app_other ) ) AS pivot_table;
说明:
PIVOT里的MAX(col2):因为你的数据中每个id和col3的组合只有一行,所以用MAX、MIN甚至SUM都能得到正确的col2值;FOR col3 IN (...):这里要把所有需要转成列的app名称列出来,并且用AS指定最终的列名(和你要的表头一致);- 如果需要把空值默认填0,可以把聚合函数改成
MAX(COALESCE(col2, 0))。
方案2:低版本Hive(不支持PIVOT,兼容所有版本)
如果你的Hive版本低于2.3.0,用GROUP BY加CASE WHEN的组合也能实现,逻辑是按id分组,每个app列单独判断取值:
SELECT id, MAX(CASE WHEN col3 = 'app_3' THEN col2 ELSE 0 END) AS app_3, MAX(CASE WHEN col3 = 'app_9' THEN col2 ELSE 0 END) AS app_9, MAX(CASE WHEN col3 = 'app_18' THEN col2 ELSE 0 END) AS app_18, MAX(CASE WHEN col3 = 'app_2' THEN col2 ELSE 0 END) AS app_2, MAX(CASE WHEN col3 = 'app_12' THEN col2 ELSE 0 END) AS app_12, MAX(CASE WHEN col3 = 'app_other' THEN col2 ELSE 0 END) AS app_other FROM app_data GROUP BY id;
说明:
GROUP BY id:把同一id的所有行聚合到一起;CASE WHEN:针对每个app名称,判断当前行是否是该app,如果是就取col2的值,否则取0;MAX():因为同一id下每个app只会出现一次,MAX会保留那个唯一的有效值,其他0会被忽略,最终得到正确的列值。
验证结果
不管用哪种方案,针对你给出的输入数据,都会得到你想要的输出:
id app_3 app_9 app_18 app_2 app_12 app_other 5314|43045.9637152778 0 0 0 0 0 1
内容的提问来源于stack exchange,提问作者Bhaskar
相关产品推荐
相关产品推荐

