如何在Hive中按ID分组合并多列非空日期数据
问题描述
原始数据
| ID | Date1 | Date2 | Date3 |
|---|---|---|---|
| 1 | 2022/01/01 | null | null |
| 1 | null | 2021/04/01 | null |
| 2 | 2022/03/01 | null | null |
| 2 | null | 2021/06/01 | null |
| 3 | 2022/01/01 | null | null |
| 4 | null | 2021/04/01 | null |
期望结果
| ID | Date1 | Date2 | Date3 |
|---|---|---|---|
| 1 | 2022/01/01 | 2021/04/01 | null |
| 2 | 2022/03/01 | 2021/06/01 | null |
| 3 | 2022/01/01 | null | null |
| 4 | null | 2021/04/01 | null |
尝试按ID分组时触发错误:expression not in group by key,需解决该问题并实现数据合并。
解决方案
这个错误的核心原因是SQL标准要求GROUP BY子句必须包含所有非聚合字段——如果直接把Date1、Date2、Date3放到SELECT里却没加入GROUP BY,就会触发该错误。结合你的需求(每个ID下各日期字段最多一个非空值),可以用聚合函数实现,无需将日期字段加入GROUP BY。
通用SQL方案(适配MySQL、PostgreSQL、SQL Server等多数数据库)
使用MAX()或MIN()聚合函数,它们会自动忽略null值,返回每个ID下对应日期字段的唯一非空值;如果该字段全为null,则返回null,完全匹配期望结果:
SELECT ID, MAX(Date1) AS Date1, MAX(Date2) AS Date2, MAX(Date3) AS Date3 FROM your_table GROUP BY ID;
Spark SQL专属方案
如果是在Spark SQL中遇到该问题,除了上述通用方案,还可以临时调整SQL模式绕过限制(不推荐长期使用,仅作调试用):
SET spark.sql.sqlansi.enabled=false; -- 或 SET spark.sql.groupByOrdinal=true;
但更规范的做法还是使用聚合函数,避免依赖非标准配置。
内容的提问来源于stack exchange,提问作者JCGamboa
相关产品推荐
相关产品推荐

