如何将SQL表多列合并为一列,填充非空列对应的列名
问题原因梳理
- 原有代码错误点:
- 新增计算列的语法错误,不需要加
SELECT关键字 CASE语句格式错误,缺少END闭合,重复写了多余的CASE关键字- 数字开头的列名没有加方括号
[]包裹,会被SQL引擎识别为数值而非列名 - 原90、80、70列是
varchar类型,需要显式转换为int才能匹配新增列的类型要求 - 你写的计算列会依赖原有的90、80、70列,后续删除原列时会触发依赖报错,因此不能用计算列实现,需要改为新增普通列后手动赋值
DROP COLUMN语法错误,不需要加括号
- 新增计算列的语法错误,不需要加
可运行示例代码
-- 步骤1:新增int类型的m_agl列 ALTER TABLE [dbo].[my_table] ADD [m_agl] INT NULL GO -- 步骤2:按照规则给m_agl列赋值(CASE写法) UPDATE [dbo].[my_table] SET [m_agl] = CASE WHEN [90] IS NOT NULL THEN CAST([90] AS INT) WHEN [80] IS NOT NULL THEN CAST([80] AS INT) WHEN [70] IS NOT NULL THEN CAST([70] AS INT) ELSE NULL END GO -- 步骤3:删除原有三个旧列 ALTER TABLE [dbo].[my_table] DROP COLUMN [90], [80], [70] GO
如果你更习惯用IIF写法,步骤2的赋值逻辑也可以替换为以下代码,效果完全一致:
-- IIF写法的赋值逻辑 UPDATE [dbo].[my_table] SET [m_agl] = CAST( IIF([90] IS NOT NULL, [90], IIF([80] IS NOT NULL, [80], IIF([70] IS NOT NULL, [70], NULL))) AS INT ) GO
注意事项
- 你描述中说明90、80、70三列最多只有一列非空,因此CASE的判断顺序不需要额外处理冲突,优先匹配到非空列就取值即可
CAST函数是为了把原varchar类型的列值转为int类型,如果原列的varchar值里有非数字内容,需要提前做数据清洗避免转换报错- 先完成UPDATE赋值后再删除原列,可以避免依赖问题导致删除失败
内容的提问来源于stack exchange,提问作者PJ99
相关产品推荐
相关产品推荐

