列转换行 IF OBJECT_ID('tb') IS NOT NULL DROP TABLE tb go CREATE TABLE tb(姓名 VARCHAR(10),语文 INT,数学 INT,物理 INT) INSERT INTO tb VALUES('张三',74,83,93) INSERT INTO tb VALUES('李四',74,84,94) go SELECT * FROM tb 动态写法 declare @sql varchar(8000) select @sql=isnull(@sql+' union all ','')+' select 姓名, [课程]=' +quotename(Name,'''')+' , [分数] = '+quotename(Name)+' from tb' from syscolumns where Name!='姓名'and ID=object_id('tb')--表名tb,不包含列名为姓名的其他列 order by colid exec(@sql+' order by 姓名') 静态写法 select * from ( select 姓名,课程='语文',分数=语文 from tb union all select 姓名,课程='数学',分数=数学 from tb union all select 姓名,课程='物理',分数=物理 from tb )t order by 姓名,case 课程 when'语文'then 1 when'数学' then 2 when '物理'then 3 end 行转列 CREATE TABLE tb1(姓名 VARCHAR(10),课程 VARCHAR(10),分数 INT) insert into tb1 VALUES ('张三','语文',74) insert into tb1 VALUES ('张三','数学',83) insert into tb1 VALUES ('张三','物理',93) insert into tb1 VALUES ('李四','语文',74) insert into tb1 VALUES ('李四','数学',84) insert into tb1 VALUES ('李四','物理',94) 固定写法 SELECT * FROM tb1 pivot( MAX(分数) FOR 课程 IN (语文,数学,物理))a 动态写法 --SQL SERVER 2000动态SQL,指课程不止语文、数学、物理这三门课程。(以下同) --变量按sql语言顺序赋值 declare @sql varchar(500) set @sql='select 姓名' select @sql=@sql+' , max(case 课程 when '''+课程+''' then 分数 else 0 end)['+课程+']' from(select distinct 课程 from tb1)a--同from tb group by课程,默认按课程名排序 set @sql=@sql+' from tb1 group by 姓名' exec(@sql) --使用isnull(),变量先确定动态部分 declare @sql varchar(8000) select @sql=isnull(@sql+',','')+' max(case 课程 when '''+课程+''' then 分数 else 0 end) ['+课程+']' from(select distinct 课程 from tb1)as a set @sql='select 姓名,'+@sql+' from tb1 group by 姓名' exec(@sql)