当前位置: 首页
数据库
玩转-SQL2005数据库行列转换

玩转-SQL2005数据库行列转换

热心网友 时间:2026-04-30
转载

SQL Server 列转行创新方法:独家利用 SysColumns 系统表实现

在 SQL Server 数据转换中,列转行操作常常让开发者感到棘手。本文分享一种高效且独特的实现思路,该方法巧妙运用了系统表 SysColumns,经过笔者实践验证,在常规方案之外提供了一种新颖的解决方案。下面我们将从基础的行转列讲起,逐步深入至核心的列转行技巧。

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

(一)SQL Server 行转列标准实现方法

行转列(PIVOT)是数据处理中的常见需求,其核心目标是将行数据中的特定值转换为结果集中的多个列。标准方法是结合动态 SQL 与 CASE WHEN 条件判断来实现。

首先,我们通过一个直观的效果图来明确转换目标:

第一步:创建测试数据表
我们首先建立一个学生成绩表,用于后续的演示:

复制代码

代码如下:
CREATE TABLE RowTest(
   [Name] [nvarchar](10) NULL,--學生姓名
   [Course] [nvarchar](10) NULL,--課程科目
   [Record] [int] NULL--考試分數
)

第二步:插入模拟数据
向表中添加结构化的测试数据,以便清晰展示转换过程:

复制代码

代码如下:
insert into RowTest values ('张三','语文','91')
insert into RowTest values ('张三','数学','92')
insert into RowTest values ('张三','英语','93')
insert into RowTest values ('张三','生物','94')
insert into RowTest values ('张三','物理','95')
insert into RowTest values ('张三','化学','96')

insert into RowTest values ('李四','语文','81')
insert into RowTest values ('李四','数学','82')
insert into RowTest values ('李四','英语','83')
insert into RowTest values ('李四','生物','84')
insert into RowTest values ('李四','物理','85')
insert into RowTest values ('李四','化学','86')

insert into RowTest values ('小生','语文','71')
insert into RowTest values ('小生','数学','72')
insert into RowTest values ('小生','英语','73')
insert into RowTest values ('小生','生物','74')
insert into RowTest values ('小生','物理','75')
insert into RowTest values ('小生','化学','76')

第三步:实现原理深度解析
行转列的本质是将“课程”字段中的不同取值动态地映射为结果集的列标题。技术实现上,通过 CASE WHEN 语句将对应课程的分数值填充到新生成的列中,最后使用 GROUP BY 按学生姓名进行聚合,实现一行显示所有成绩。

第四步:编写通用动态 SQL 脚本
为了适应课程科目可能动态变化的情况,采用动态 SQL 是更通用的解决方案:

复制代码

代码如下:
declare @sql nvarchar(max)
set @sql='select Name'
select @sql=@sql+','+'isnull(max( case when Course='''+TCourse.Course+''' then Record end ),0) as ['+TCourse.Course+']'
  from (select distinct Course from RowTest)TCourse

set @sql=@sql+' from RowTest group by Name order by Name'

print @sql
exec(@sql)

关键技术点说明:
此脚本首先获取所有不重复的课程名称,构成一个临时集合(TCourse)。随后通过字符串拼接循环,为每一门课程生成对应的 CASE WHEN 条件列,最终组装成完整的、可执行的查询语句,完美实现动态行转列。

第五步:扩展场景与边界测试
1. 处理重复数据: 假设为“小生”额外添加一条生物课成绩:

复制代码

代码如下:
insert into dbo.RowTest values ('小生','生物','110')

此时,若动态 SQL 中省略 MAX() 聚合函数,执行将会报错。原因在于同一学生同一课程出现多行记录时,必须通过聚合函数来确定最终显示哪一个数值。

2. 测试动态扩展性: 新增一门“计算机”课程数据:

复制代码

代码如下:
insert into dbo.RowTest values ('小生','計算機','110')

再次执行之前的动态 SQL,会发现结果集中自动增加了“计算机”列。对于未选修该课程的学生,其对应列值显示为 0。这充分证明了该方法的灵活性与可扩展性。

至此,SQL Server 行转列的通用实现方法已完整阐述。

(二)SQL Server 列转行独家创新方案

接下来重点探讨更具挑战性的列转行(UNPIVOT)操作。传统方法依赖多个 UNION ALL 语句,代码冗长且不易维护。笔者提出一种基于系统表的新思路,更为简洁高效。

列转行的目标效果如下图所示:

第一步:创新思路揭秘
常见方案需要为每一列手动编写 UNION ALL 子句,列数增加时代码量同步增长。本文的创新方法核心在于:首先,动态获取目标表除主键(或姓名列)外的所有列名,这通过查询系统表 SysColumns 实现。然后,将原表与这个“列名结果集”进行关联,从而将一行数据“展开”成多行(每行对应一个列名)。最后,通过条件判断动态获取原表对应列的值。

第二步:构建列式存储测试表
创建一个典型的宽表结构,各科目成绩以独立列的形式存储:

复制代码

代码如下:
create table CoulumTest
(
  Name nvarchar(10),
  语文  int,
  数学 int,
  英语 int
)

第三步:准备测试数据
向表中插入示例数据:

复制代码

代码如下:
insert into CoulumTest values(N'张三',90,91,92)
insert into CoulumTest values(N'李四',80,81,82)

第四步:核心实现代码解析
关键实现仅需一条查询语句,极大简化了操作:

复制代码

代码如下:
select CT.Name, Col.name as 课程,
(case when Col.name=N'语文' then CT.语文
      when Col.name=N'数学' then CT.数学
      when Col.name=N'英语' then CT.英语
 end ) as 分数
from CoulumTest CT
left join (select name from SysColumns Where id=Object_Id('CoulumTest')) Col on Col.name <> 'Name'

这条语句的精妙之处在于:通过左连接系统表 SysColumns,获取当前表的所有列名,并过滤掉非转换列(如‘Name’)。然后,利用 CASE WHEN 语句,根据匹配到的列名,从原表对应列中取出数值。

当然,此方法仍有优化空间:目前的 CASE WHEN 需要显式列出每个列名。是否存在一种更通用的方式,能够直接根据 Col.name 动态引用 CT 表中的列,而无需硬编码条件分支?这作为一个开放性问题,留给读者进一步思考和探索,也欢迎更多数据库高手分享更优解。

来源:https://www.jb51.net/article/43764.htm

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
sql语句中数据库别名命名和查询问题解析

sql语句中数据库别名命名和查询问题解析

查询出低于菜品平均价格的菜品信息 (展示出菜品名称、菜品价格) 问题1:为什么下面代码不对 select d name,d price,a vg(d price) from dish as d where d price < a vg(d price) 这行代码一拿出来,很多初学者都会犯迷糊,但其

时间:2026-04-30 20:26
SQLDeveloper表复制的实现

SQLDeveloper表复制的实现

步骤 当数据量比较大时,相比一条条地执行INSERT语句,这种方法效率的提升是立竿见影的。不过,有个关键点需要留心:具体的操作逻辑是直接覆盖目标表原有数据,还是进行增量合并,这个取决于你的工具设置和表结构。稳妥起见,强烈建议你先自己创建一个测试用的Demo表演练一遍,摸清实际行为,避免在生产环境中间

时间:2026-04-30 20:26
SQLServer数据库表结构使用SSMS和Navicat导出教程

SQLServer数据库表结构使用SSMS和Navicat导出教程

在数据库管理和开发过程中,导出表结构是一项常见的任务,尤其是在数据库设计、数据迁移、备份以及生成文档时。本文将详细介绍如何使用 SQL Server Management Studio (SSMS) 和 Na vicat 来导出 SQL Server 数据库的表结构,包括表名、字段名、数据类型、注释

时间:2026-04-30 20:26
MySQL8中的保留关键字陷阱之当表名“lead”引发SQL语法错误的解决方案

MySQL8中的保留关键字陷阱之当表名“lead”引发SQL语法错误的解决方案

问题现象 很多开发者可能都踩过这个坑:一个原本运行得好好的业务系统,在执行下面这条再简单不过的查询时,突然就报错了。 SELECT COUNT(*) AS total FROM lead WHERE deleted_flag = 0 数据库抛出的错误非常明确,直指语法问题: You ha ve an

时间:2026-04-30 20:25
Mysql因为字段字符集编码的问题导致索引没生效的解决方案

Mysql因为字段字符集编码的问题导致索引没生效的解决方案

深入解析SQL查询性能问题:字符集不一致导致的索引失效 SELECT s department_name AS departmentName, cps purchase_type AS purchaseType FROM settlement_records s LEFT JOIN common_p

时间:2026-04-30 20:25
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜
热门教程
更多
  • 游戏攻略
  • 安卓教程
  • 苹果教程
  • 电脑教程