如何连接格式差异的两张数据表?附示例表及期望输出
解决宽表与长表的关联问题
看起来你是想把宽格式的Table2和长格式的Table1关联,得到每个ID-年-月对应的数值对吧?之前用CASE JOIN不对的原因是CASE通常用来做行内判断,而你需要的是把列转成行的逆透视操作,再做关联。我来给你详细说明实现方式:
思路拆解
Table2是按月份列(Jan、Feb、Mar)存储数据的,我们需要先把这些列转换成「Month数字值+对应Data」的行结构,让它和Table1的(ID、Year、Month)结构对齐,之后再通过这三个字段关联,就能得到你想要的输出。
通用SQL实现(兼容绝大多数数据库)
如果你的数据库不支持专门的逆透视函数,用UNION ALL是最稳妥的方式,几乎所有SQL数据库都支持:
SELECT t1.ID, t1.Year, t1.Month, t2_pivoted.Data FROM Table1 t1 INNER JOIN ( -- 把Table2的月份列转成行 SELECT ID, Year, 1 AS Month, Jan AS Data FROM Table2 UNION ALL SELECT ID, Year, 2 AS Month, Feb AS Data FROM Table2 UNION ALL SELECT ID, Year, 3 AS Month, Mar AS Data FROM Table2 -- 如果有更多月份,继续添加UNION ALL语句即可 ) t2_pivoted ON t1.ID = t2_pivoted.ID AND t1.Year = t2_pivoted.Year AND t1.Month = t2_pivoted.Month
简洁版(支持UNPIVOT的数据库,如SQL Server、Oracle)
如果你的数据库支持UNPIVOT语法,可以用更简洁的写法:
SELECT t1.ID, t1.Year, t1.Month, t2_pivoted.Data FROM Table1 t1 INNER JOIN ( SELECT ID, Year, -- 将月份名称转换为数字 CASE MonthName WHEN 'Jan' THEN 1 WHEN 'Feb' THEN 2 WHEN 'Mar' THEN 3 -- 其他月份依次补充 END AS Month, Data FROM Table2 -- 逆透视:把Jan/Feb/Mar列转成MonthName和Data的行 UNPIVOT ( Data FOR MonthName IN (Jan, Feb, Mar) ) AS unpvt ) t2_pivoted ON t1.ID = t2_pivoted.ID AND t1.Year = t2_pivoted.Year AND t1.Month = t2_pivoted.Month
效果说明
执行上述SQL后,Table2会被转换为和Table1结构匹配的长表,再通过ID、Year、Month三个字段精准关联,就能得到你期望的「ID Year Month Data」格式的结果。
内容的提问来源于stack exchange,提问作者Jeff McClain
相关产品推荐
相关产品推荐

