You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server实现带动态列的行转列(convert rows into columns)

SQL Server 无预置列名的动态行转列实现

SQL Server原生PIVOT语法要求硬编码转置后的列名,要实现根据City字段取值自动生成列的效果,通过动态SQL拼接即可完成,不需要提前固定列清单。


实现逻辑

  • 先从源表提取所有去重后的City值,转义后拼接为PIVOT需要的列名集合
  • 拼接完整的PIVOT查询语句
  • 执行动态生成的SQL返回结果

完整代码

假设你的源表名为VisitorPrice,包含[Visitor name]、City、Price三个字段,代码如下:

DECLARE @dynamic_columns NVARCHAR(MAX), @execute_sql NVARCHAR(MAX);

-- 生成动态列名清单,自动处理特殊字符转义
-- SQL Server 2017及以上版本可用STRING_AGG写法
SELECT @dynamic_columns = STRING_AGG(QUOTENAME(City), ', ')
FROM (SELECT DISTINCT City FROM VisitorPrice) AS unique_city;

-- 若使用SQL Server 2016及以下版本,替换上面的列名拼接逻辑为以下FOR XML PATH写法即可
/*
SELECT @dynamic_columns = STUFF(
    (SELECT ', ' + QUOTENAME(City)
     FROM (SELECT DISTINCT City FROM VisitorPrice) AS unique_city
     FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)'),
1, 2, '')
*/

-- 拼接PIVOT查询语句
SET @execute_sql = N'
SELECT [Visitor name], ' + @dynamic_columns + N'
FROM VisitorPrice
PIVOT (
    MAX(Price)
    FOR City IN (' + @dynamic_columns + N')
) AS pivot_result
';

-- 执行语句输出结果
EXEC sp_executesql @execute_sql;

运行结果

针对你给出的3条Neo的示例数据,执行后会自动生成Japan、NewYork、Paris三个列,返回单条记录如下:

Visitor nameJapanNewYorkParis
Neo950001000001000000

注意事项

  • QUOTENAME()函数用于包裹City字段值,避免城市名包含空格、特殊符号时触发SQL语法错误
  • PIVOT必须搭配聚合函数使用:如果同一访客、同一城市存在多条价格记录,MAX(Price)会返回匹配到的最大价格,可根据业务需求替换为SUM、AVG、MIN等其他聚合函数
  • 后续源表新增其他城市的记录时,不需要修改代码,查询结果会自动新增对应列

内容的提问来源于stack exchange,提问作者Ali Sharafzade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:57:20