SQL行转列实现:将国家风险分数从纵向转为横向显示
纵向转横向的正确SQL写法
先假设你的原始数据表结构为country_risk,包含country_name(国家名称)和risk_score(风险分数)两个字段,数据是每个国家对应一条风险记录的纵向格式。
方法一:CASE WHEN + 聚合函数
这是通用写法,几乎所有数据库都支持,解决你之前出现多行的问题,关键是不要按国家分组,直接对整个表聚合:
SELECT SUM(CASE WHEN country_name = '中国' THEN risk_score END) AS 中国风险分数, SUM(CASE WHEN country_name = '美国' THEN risk_score END) AS 美国风险分数, SUM(CASE WHEN country_name = '日本' THEN risk_score END) AS 日本风险分数, SUM(CASE WHEN country_name = '德国' THEN risk_score END) AS 德国风险分数, SUM(CASE WHEN country_name = '法国' THEN risk_score END) AS 法国风险分数 FROM country_risk;
注:这里用SUM、MAX或MIN都可以,因为每个国家只有一条数据,聚合后会得到对应的值,不会出现NULL(只要原始数据中存在该国家的记录)。
方法二:PIVOT函数(适用于SQL Server、Oracle等支持的数据库)
解决你之前返回全NULL的问题,注意子查询必须包含透视列和聚合列,且透视列的取值要和原始数据完全匹配:
SELECT * FROM ( -- 子查询只保留需要透视的列 SELECT country_name, risk_score FROM country_risk ) AS SourceData PIVOT ( -- 聚合函数,这里用SUM/MAX/MIN均可 SUM(risk_score) -- 指定要转为列的字段,以及具体的列值(必须和原始数据一致) FOR country_name IN ([中国], [美国], [日本], [德国], [法国]) ) AS PivotResult;
之前返回全NULL的常见原因:
- 子查询遗漏了必要的字段
- 透视列的取值(如
[中国])和原始数据中的国家名称存在大小写、空格或格式差异 - 聚合函数指定错误,没有针对风险分数字段聚合
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

