如何对Healthcare_WorldBank.dbo.wb_new表执行行列转换?
解决方案:SQL实现表结构转换
要实现原表到目标表的结构转换,需要结合列转行和行转列两个核心操作,以下是两种可行的实现方案:
方案1:使用Unpivot+Pivot(推荐,适用于支持该语法的SQL Server等数据库)
先将原表的年份列拆分为行,再将指标代码(series_code)转换为独立列:
SELECT country_name, country_code, year, CHE, CAPHE, CHE_CAP, CHE_CAP_PPP FROM ( -- 子查询:把年份列拆分为行格式 SELECT country_name, country_code, series_code, -- 将yr_xxxx转换为数字年份 CASE year_col WHEN 'yr_2015' THEN 2015 WHEN 'yr_2016' THEN 2016 WHEN 'yr_2017' THEN 2017 END AS year, value FROM Healthcare_WorldBank.dbo.wb_new UNPIVOT ( -- 提取年份列对应的数值 value FOR year_col IN (yr_2015, yr_2016, yr_2017) ) AS unpvt ) AS src PIVOT ( -- 按年份分组,把不同series_code的数值聚合到对应列 MAX(value) FOR series_code IN (CHE, CAPHE, CHE_CAP, CHE_CAP_PPP) ) AS pvt;
代码说明:
UNPIVOT:把原表的宽年份结构转成长格式,每行对应一个国家、一个指标、一个年份的数值。PIVOT:以year为分组依据,将不同series_code的数值映射到独立列中(用MAX是因为每组仅对应一个值,不影响结果)。- 后续若新增指标,只需在
PIVOT的IN列表中添加对应的series_code即可。
方案2:手动UNION ALL+条件聚合(兼容不支持Pivot/Unpivot的旧版数据库)
通过UNION ALL分别处理每个年份,再用条件判断将指标转成列:
-- 处理2015年数据 SELECT country_name, country_code, 2015 AS year, MAX(CASE WHEN series_code = 'CHE' THEN yr_2015 END) AS CHE, MAX(CASE WHEN series_code = 'CAPHE' THEN yr_2015 END) AS CAPHE, MAX(CASE WHEN series_code = 'CHE_CAP' THEN yr_2015 END) AS CHE_CAP, MAX(CASE WHEN series_code = 'CHE_CAP_PPP' THEN yr_2015 END) AS CHE_CAP_PPP FROM Healthcare_WorldBank.dbo.wb_new GROUP BY country_name, country_code UNION ALL -- 处理2016年数据 SELECT country_name, country_code, 2016 AS year, MAX(CASE WHEN series_code = 'CHE' THEN yr_2016 END) AS CHE, MAX(CASE WHEN series_code = 'CAPHE' THEN yr_2016 END) AS CAPHE, MAX(CASE WHEN series_code = 'CHE_CAP' THEN yr_2016 END) AS CHE_CAP, MAX(CASE WHEN series_code = 'CHE_CAP_PPP' THEN yr_2016 END) AS CHE_CAP_PPP FROM Healthcare_WorldBank.dbo.wb_new GROUP BY country_name, country_code UNION ALL -- 处理2017年数据 SELECT country_name, country_code, 2017 AS year, MAX(CASE WHEN series_code = 'CHE' THEN yr_2017 END) AS CHE, MAX(CASE WHEN series_code = 'CAPHE' THEN yr_2017 END) AS CAPHE, MAX(CASE WHEN series_code = 'CHE_CAP' THEN yr_2017 END) AS CHE_CAP, MAX(CASE WHEN series_code = 'CHE_CAP_PPP' THEN yr_2017 END) AS CHE_CAP_PPP FROM Healthcare_WorldBank.dbo.wb_new GROUP BY country_name, country_code;
代码说明:
- 每个
SELECT块单独处理一个年份的数据,用CASE筛选对应指标的年份数值,MAX用于聚合同国家同指标的唯一值。 - 用
UNION ALL合并三个年份的结果,最终得到目标表结构。
内容的提问来源于stack exchange,提问作者DataEnthusiast_22
相关产品推荐
相关产品推荐

