实现含同类记录不同币种字段的多表Union合并与Pivot转置
需求实现方案
以下两种通用方案都可以实现目标表结构:
方案1:多表直接关联(最简便)
如果三张表的User、Country字段取值完全匹配,直接关联是成本最低的实现方式,兼容所有支持JOIN语法的SQL引擎:
SELECT t1.User, t1.Country, t1.COST_USD, t2.COST_EUR, t3.COST_YEN FROM 表1 t1 LEFT JOIN 表2 t2 ON t1.User = t2.User AND t1.Country = t2.Country LEFT JOIN 表3 t3 ON t1.User = t3.User AND t1.Country = t3.Country
如果存在某张表缺失特定用户数据的场景,使用LEFT JOIN可以保留全量用户,若所有表的用户完全一致,替换为INNER JOIN即可。
方案2:UNION ALL + 转列(适配你之前的实现思路)
你之前操作失败的核心原因是UNION ALL要求所有子查询的字段数量、字段类型、字段顺序完全一致,三张表的成本字段名不同,直接UNION会出现结构不匹配的报错,调整写法如下:
写法A:聚合转列(兼容所有SQL引擎)
先统一所有子查询的字段结构,缺失的币种字段补NULL,再按用户维度聚合取非空值:
SELECT User, Country, MAX(COST_USD) AS COST_USD, MAX(COST_EUR) AS COST_EUR, MAX(COST_YEN) AS COST_YEN FROM ( SELECT User, Country, COST_USD, NULL AS COST_EUR, NULL AS COST_YEN FROM 表1 UNION ALL SELECT User, Country, NULL AS COST_USD, COST_EUR, NULL AS COST_YEN FROM 表2 UNION ALL SELECT User, Country, NULL AS COST_USD, NULL AS COST_EUR, COST_YEN FROM 表3 ) t GROUP BY User, Country
写法B:PIVOT语法实现(适配支持PIVOT的引擎,如Spark SQL、Oracle、Hive等)
先把各表数据统一为「用户+国家+币种+成本」的长表结构,再用PIVOT转成宽表:
SELECT * FROM ( SELECT User, Country, 'USD' AS currency, COST_USD AS cost FROM 表1 UNION ALL SELECT User, Country, 'EUR' AS currency, COST_EUR AS cost FROM 表2 UNION ALL SELECT User, Country, 'YEN' AS currency, COST_YEN AS cost FROM 表3 ) t PIVOT ( MAX(cost) FOR currency IN ('USD' AS COST_USD, 'EUR' AS COST_EUR, 'YEN' AS COST_YEN) )
内容的提问来源于stack exchange,提问作者tom
相关产品推荐
相关产品推荐

