如何在SparkSQL中实现类似unionByName的按列名合并?
在SparkSQL中实现类似unionByName的按列名合并功能
问题场景
在旧版SparkSQL中执行如下查询:
select * from (select 10 as student_type,'henry' as student_name union select 'tom' as student_name,90 as student_type );
得到的结果如下:
| student_type | student_name |
|---|---|
| 10 | henry |
| tom | 90 |
可见SparkSQL的UNION是按列的位置而非列名匹配,导致结果不符合预期。而DataFrame API提供了unionByName方法可以按列名合并DataFrame,现在需要在SparkSQL中实现相同的按列名合并效果,期望得到的结果如下:
| student_type | student_name |
|---|---|
| 10 | henry |
| 90 | tom |
解决办法
1. Spark 3.1及以上版本:使用UNION BY NAME语法
Spark 3.1及后续版本原生支持UNION BY NAME(若需保留重复行,可使用UNION ALL BY NAME),该语法会自动按列名对齐两个子查询的结果,无需手动调整列顺序:
select * from (select 10 as student_type,'henry' as student_name union by name select 'tom' as student_name,90 as student_type );
执行后即可得到符合预期的结果。
2. 旧版本Spark:手动对齐列顺序
如果使用的Spark版本低于3.1,需要手动调整第二个子查询的列顺序,使其与第一个子查询的列名顺序完全一致:
select * from (select 10 as student_type,'henry' as student_name union select 90 as student_type, 'tom' as student_name );
也可以显式指定列名,避免依赖*的默认列顺序,让逻辑更清晰:
select student_type, student_name from (select 10 as student_type,'henry' as student_name union select 90 as student_type, 'tom' as student_name );
内容的提问来源于stack exchange,提问作者Ray
相关产品推荐
相关产品推荐

