SQL列转行

SQL列转行

生成

sql代码

复制代码
 
生成静态:
select *
from (select sname,[Course ] ='数学',[Score]=[数学] from Tb_students union all
select sname,[Course]='英语',[Score]=[英语] from Tb_students union all
select sname,[Course]='语文',[Score]=[语文] from Tb_students)t
order by sname,case [Course] when '语文' then 1 when '数学' then 2 when '英语' then 3 end
go
 --列转行的静态方案:UNPIVOT,sql2005及以后版本
 
  SELECT sname,Subject, grade
  from dbo.Tb_students
  unpivot(grade for Subject in([语文],[数学],[英语]))as up
  GO
  
  
  --列转行的动态方案:UNPIVOT,sql2005及以后版本
  --因为行是动态所以这里就从INFORMATION_SCHEMA.COLUMNS视图中获取列来构造行,同样也使用了XML处理。
 declare @s nvarchar(4000)
select @s=isnull(@s+',','')+quotename(Name)
from syscolumns where ID=object_id('Tb_students') and Name not in('sname')
order by Colid
exec('select sname,[Subject],[grade] from Tb_students unpivot ([grade] for [Subject] in('+@s+'))b')

go
select
    sname,[Subject],[grade]
from
    Tb_students
unpivot
    ([grade] for [Subject] in([数学],[英语],[语文]))b
复制代码

 

### 实现转行功能的 SQL 方法 在 SQL 查询中,可以通过 `UNPIVOT` 函数或者动态 SQL 的方式来实现转行的功能。以下是两种常见的方法及其具体实现。 #### 使用 UNPIVOT 函数 `UNPIVOT` 是 SQL Server 提供的一种内置函数,专门用于将表中的转换为行。其基本语法如下: ```sql SELECT studentname, subject, grade FROM stugrade UNPIVOT ( grade FOR subject IN ([语文], [数学], [英语], [生物]) ) AS unpvt; ``` 上述代码的作用是从 `stugrade` 表中选取学生姓名 (`studentname`) 和成绩对应的科目与分数,并通过 `UNPIVOT` 将指定的 `[语文]`, `[数学]`, `[英语]`, `[生物]` 转换为行[^2]。 #### 动态 SQL 方式 当需要处理的名较多或不确定时,可以采用动态 SQL 来构建查询语句。以下是一个完整的例子: ```sql DECLARE @sql NVARCHAR(MAX); SET @sql = N''; WITH sub AS ( SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'stugrade' AND column_name != 'studentname' ) SELECT @sql += N'SELECT studentname, ''' + COLUMN_NAME + N''' AS subject, ' + COLUMN_NAME + N' AS grade FROM stugrade UNION ALL ' FROM sub; -- 去掉最后一个多余的 "UNION ALL" SET @sql = SUBSTRING(@sql, 1, LEN(@sql) - 9); -- 打印调试用的 SQL 语句 PRINT (@sql); -- 执行动态生成的 SQL 语句 EXEC (@sql); ``` 此脚本会自动获取 `stugrade` 表中除 `studentname` 外的所有,并将其作为独立的行输出[^1]。 --- ### MySQL 中的替代方案 如果使用的数据库是 MySQL,则由于不支持 `UNPIVOT` 关键字,需借助联合查询(`UNION ALL`)手动完成类似的转行操作。例如: ```sql SELECT studentname, '语文' AS subject, chinese AS grade FROM stugrade UNION ALL SELECT studentname, '数学', math FROM stugrade UNION ALL SELECT studentname, '英语', english FROM stugrade UNION ALL SELECT studentname, '生物', biology FROM stugrade; ``` 这种方法虽然简单明了,但在面对大量时显得不够灵活[^3]。 --- ### 性能优化建议 对于大规模数据集,在执行转行操作前应考虑以下几个方面以提高性能: - **索引设计**:确保涉及的字段已建立适当索引。 - **分区策略**:合理利用表分区减少扫描范围。 - **临时存储**:先将原始数据导出到中间表再做进一步加工可能更高效。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值