Spark SQL执行UNION合并查询后未展示全部列问题求解
问题核心原因
你对UNION的使用逻辑理解有误,UNION的作用是纵向拼接两个查询的结果行,不是横向合并不同查询的列,因此不会同时保留两个查询的不同指标列。UNION执行时遵循以下规则:
- 两个
SELECT语句返回的列数必须完全一致 - 对应位置的列数据类型必须兼容
- 最终结果的列名完全以第一个
SELECT语句定义的列名为准
你的两个查询第二列分别是VL_MED_FAT和MAX_VL_RPTD_UTZO,执行UNION时会把第二个查询的MAX_VL_RPTD_UTZO的值直接填充到第一个查询的VL_MED_FAT列下,列名沿用第一个查询的VL_MED_FAT,自然不会出现MAX_VL_RPTD_UTZO列。
适配不同需求的解决方案
如果你需要同时保留两个指标作为不同列
应该使用JOIN按关联字段拼接两个临时视图的列,示例代码如下:
spark.sql(''' SELECT COALESCE(a.CD_CLI, b.CD_CLI) AS CD_CLI, a.VL_MED_FAT, b.MAX_VL_RPTD_UTZO, '2017-01-31' AS DT_MVTC FROM media_vl_fatura_2017_01_31 a FULL OUTER JOIN vl_rptd_max_utzo_2017_01_31 b ON a.CD_CLI = b.CD_CLI ''').createOrReplaceTempView('new_table')
这里用FULL OUTER JOIN可以保留两边所有的客户ID,避免数据丢失。
如果你确实需要纵向拼接两行数据
需要统一列名,额外增加字段区分不同指标类型,同时建议用UNION ALL代替UNION(不需要去重时性能更高),示例代码如下:
spark.sql(''' SELECT CD_CLI, VL_MED_FAT AS metric_value, 'VL_MED_FAT' AS metric_name, '2017-01-31' as DT_MVTC FROM in_lim_fat WHERE DT_MVTC BETWEEN '2016-07-31' AND '2016-12-31' GROUP BY CD_CLI UNION ALL SELECT CD_CLI, MAX(VL_RPTD_UTZO) AS metric_value, 'MAX_VL_RPTD_UTZO' AS metric_name, '2017-01-31' AS DT_MVTC FROM vl_rptd_utzo WHERE DT_EXTC BETWEEN '2016-07-31' AND '2016-12-31' GROUP BY CD_CLI ''').createOrReplaceTempView('new_table')
内容的提问来源于stack exchange,提问作者Silvio sjsj
相关产品推荐
相关产品推荐

