怎样才能将行转成列??

birdybike 2008-01-14 02:46:44
表k

户号 户名 类型 倍率 数量
1 张三 102 20 3650
1 张三 103 20 720
1 张三 104 20 280
1 张三 106 20 4650
2 李四 102 40 100
2 李四 103 40 200
2 李四 104 40 300
2 李四 106 40 600
3 ………

转换成

户号 户名 102数量 103数量 104数量 106数量
1 张三 3650 720 280 4650
2 李四 100 200 300 600
3 ……
...全文
128 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ITMiner 2008-01-18
  • 打赏
  • 举报
回复
SQL2000就用case when... then...else... end 语句
SQL2005就用PIVOT,这是增加的新特性
Thank you!
yang_dgut 2008-01-18
  • 打赏
  • 举报
回复
關於交叉表的小問題!
netcellsoft 2008-01-16
  • 打赏
  • 举报
回复
这个问题,已经有很多人问了,论坛里有.
JL99000 2008-01-14
  • 打赏
  • 举报
回复
if object_id('tb') is not null
drop table tb
go
create table tb(户号 int,户名 varchar(10),类型 varchar(10),倍率 int,数量 varchar(10))
insert tb
select 1,'张三','102',20,'3650' union all
select 1,'张三','103',20,'720' union all
select 1,'张三','104',20,'280' union all
select 1,'张三','106',20,'4650' union all

select 2,'李四','102',40,'100' union all
select 2,'李四','103',40,'200' union all
select 2,'李四','104',40,'300' union all
select 2,'李四','106',40,'600' union all
select 3,'……',null,null,null

declare @sql varchar(1000)
set @sql='select 户号,户名,'
select @sql=@sql+ 'max(case when 类型='''+a.类型+''' then 数量 else ' +'''''' +' end) as ['+a.类型+'数量] ,'
from (select distinct 类型 from tb where 类型 is not null) a
set @sql=substring(@sql,1,len(@sql)-1)+' from tb group by 户号,户名 order by 户号'
print @sql
exec(@sql)

楼主接分了
loworth 2008-01-14
  • 打赏
  • 举报
回复

/*最精简 不带游标的*/
DECLARE @SQL VARCHAR(8000)

SET @SQL='SELECT [户号],[户名]'



SELECT @SQL=@SQL+','+CAST([类型] AS VARCHAR(4))+'数量=MAX(CASE [类型] WHEN '''+CAST([类型] AS VARCHAR(4))+''' THEN [数量] ELSE NULL END)'
FROM
(
SELECT DISTINCT [类型] FROM [k] ORDER BY [类型]
) t

SELECT @SQL=@SQL+' FROM [k] GROUP BY [户号],[户名]'
EXEC(@SQL)
loworth 2008-01-14
  • 打赏
  • 举报
回复

DECLARE @SQL VARCHAR(8000)

SET @SQL='SELECT [户号],[户名]'



SELECT @SQL=@SQL+','+CAST([类型] AS VARCHAR(4))+'数量=MAX(CASE [类型] WHEN '''+CAST([类型] AS VARCHAR(4))+''' THEN [数量] ELSE NULL END)'
FROM
(
SELECT DISTINCT [类型] FROM [k] ORDER BY [类型]
) t

SELECT @SQL=@SQL+' FROM [k] GROUP BY [户号],[户名]'
birdybike 2008-01-14
  • 打赏
  • 举报
回复
好像不行啊,帮忙写个完整的吧
liangCK 2008-01-14
  • 打赏
  • 举报
回复
create table ta(CustomerName varchar(6),questionId int,answer varchar(6))
insert ta select '贝凤丽',163 ,'是'
insert ta select '贝凤丽', 164 ,'是'
insert ta select '贝凤丽', 165 ,'是'
insert ta select '贝凤丽', 166 ,'否'
insert ta select '贝凤丽', 167 ,'是'
insert ta select '贝凤丽', 168 ,'是'
insert ta select '蔡春燕', 163 ,'是'
insert ta select '蔡春燕', 164 ,'是'
insert ta select '蔡春燕', 165 ,'是'
insert ta select '蔡春燕', 166 ,'是'
insert ta select '蔡春燕', 167 ,'是'
insert ta select '蔡春燕', 168 ,'是'
insert ta select '蔡佩琦', 163 ,'是'
insert ta select '蔡佩琦', 164 ,'是'
insert ta select '蔡佩琦', 165 ,'是'
insert ta select '蔡佩琦', 166 ,'是'
insert ta select '蔡佩琦', 167 ,'是'
insert ta select '蔡佩琦', 168 ,'否'
insert ta select '夏国平', 163 ,'是'
insert ta select '夏国平', 164 ,'是'
insert ta select '夏国平', 165 ,'是'
insert ta select '夏国平', 166 ,'是'
insert ta select '夏国平', 167 ,'是'
insert ta select '夏国平', 168 ,'是'
insert ta select '夏国平', 169 ,'未答'
insert ta select '夏国平', 170,'未答'

go
declare @s varchar(8000)
declare @I int

select @i = min(questionid)- 1 from ta
set @s = 'select CustomerName'
select @s =@s + ',['+ltrim(questionId - @i)+']=max(case when questionId = '+ltrim(questionId)+' then answer else '''' end)'
from (select distinct questionid from ta) a
exec( @s+ ' from ta group by CustomerName')
/*
CustomerName 1 2 3 4 5 6 7 8
------------ ------ ------ ------ ------ ------ ------ ------ ------
贝凤丽 是 是 是 否 是 是
蔡春燕 是 是 是 是 是 是
蔡佩琦 是 是 是 是 是 否
夏国平 是 是 是 是 是 是 未答 未答


*/

drop table ta
liangCK 2008-01-14
  • 打赏
  • 举报
回复
/*
普通行列转换
(爱新觉罗.毓华 2007-11-18于海南三亚)

假设有张学生成绩表(tb)如下:
Name Subject Result
张三 语文  74
张三 数学  83
张三 物理  93
李四 语文  74
李四 数学  84
李四 物理  94
*/

-------------------------------------------------------------------------
/*
想变成
姓名 语文 数学 物理
---------- ----------- ----------- -----------
李四 74 84 94
张三 74 83 93
*/

create table tb
(
Name varchar(10) ,
Subject varchar(10) ,
Result int
)

insert into tb(Name , Subject , Result) values('张三' , '语文' , 74)
insert into tb(Name , Subject , Result) values('张三' , '数学' , 83)
insert into tb(Name , Subject , Result) values('张三' , '物理' , 93)
insert into tb(Name , Subject , Result) values('李四' , '语文' , 74)
insert into tb(Name , Subject , Result) values('李四' , '数学' , 84)
insert into tb(Name , Subject , Result) values('李四' , '物理' , 94)
go

--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
max(case subject when '语文' then result else 0 end) 语文,
max(case subject when '数学' then result else 0 end) 数学,
max(case subject when '物理' then result else 0 end) 物理
from tb
group by name
/*
姓名 语文 数学 物理
---------- ----------- ----------- -----------
李四 74 84 94
张三 74 83 93
*/

--动态SQL,指subject不止语文、数学、物理这三门课程。
declare @sql varchar(8000)
set @sql = 'select Name as ' + '姓名'
select @sql = @sql + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'
from (select distinct Subject from tb) as a
set @sql = @sql + ' from tb group by name'
exec(@sql)
/*
姓名 数学 物理 语文
---------- ----------- ----------- -----------
李四 84 94 74
张三 83 93 74
*/

-------------------------------------------------------------------
/*加个平均分,总分
姓名 语文 数学 物理 平均分 总分
---------- ----------- ----------- ----------- -------------------- -----------
李四 74 84 94 84.00 252
张三 74 83 93 83.33 250
*/

--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
max(case subject when '语文' then result else 0 end) 语文,
max(case subject when '数学' then result else 0 end) 数学,
max(case subject when '物理' then result else 0 end) 物理,
cast(avg(result*1.0) as decimal(18,2)) 平均分,
sum(result) 总分
from tb
group by name
/*
姓名 语文 数学 物理 平均分 总分
---------- ----------- ----------- ----------- -------------------- -----------
李四 74 84 94 84.00 252
张三 74 83 93 83.33 250
*/

--动态SQL,指subject不止语文、数学、物理这三门课程。
declare @sql1 varchar(8000)
set @sql1 = 'select Name as ' + '姓名'
select @sql1 = @sql1 + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'
from (select distinct Subject from tb) as a
set @sql1 = @sql1 + ' , cast(avg(result*1.0) as decimal(18,2)) 平均分,sum(result) 总分 from tb group by name'
exec(@sql1)
/*
姓名 数学 物理 语文 平均分 总分
---------- ----------- ----------- ----------- -------------------- -----------
李四 84 94 74 84.00 252
张三 83 93 74 83.33 250
*/

drop table tb

---------------------------------------------------------
---------------------------------------------------------
/*
如果上述两表互相换一下:即

姓名 语文 数学 物理
张三 74  83  93
李四 74  84  94

想变成
Name Subject Result
---------- ------- -----------
李四 语文 74
李四 数学 84
李四 物理 94
张三 语文 74
张三 数学 83
张三 物理 93
*/

create table tb1
(
姓名 varchar(10) ,
语文 int ,
数学 int ,
物理 int
)

insert into tb1(姓名 , 语文 , 数学 , 物理) values('张三',74,83,93)
insert into tb1(姓名 , 语文 , 数学 , 物理) values('李四',74,84,94)

select * from
(
select 姓名 as Name , Subject = '语文' , Result = 语文 from tb1
union all
select 姓名 as Name , Subject = '数学' , Result = 数学 from tb1
union all
select 姓名 as Name , Subject = '物理' , Result = 物理 from tb1
) t
order by name , case Subject when '语文' then 1 when '数学' then 2 when '物理' then 3 when '总分' then 4 end

--------------------------------------------------------------------
/*加个平均分,总分
Name Subject Result
---------- ------- --------------------
李四 语文 74.00
李四 数学 84.00
李四 物理 94.00
李四 平均分 84.00
李四 总分 252.00
张三 语文 74.00
张三 数学 83.00
张三 物理 93.00
张三 平均分 83.33
张三 总分 250.00
*/

select * from
(
select 姓名 as Name , Subject = '语文' , Result = 语文 from tb1
union all
select 姓名 as Name , Subject = '数学' , Result = 数学 from tb1
union all
select 姓名 as Name , Subject = '物理' , Result = 物理 from tb1
union all
select 姓名 as Name , Subject = '平均分' , Result = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb1
union all
select 姓名 as Name , Subject = '总分' , Result = 语文 + 数学 + 物理 from tb1
) t
order by name , case Subject when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 end

drop table tb1
liangCK 2008-01-14
  • 打赏
  • 举报
回复
create table tb(户号 int,户名 varchar(20),类型 int,倍率 int,数量 int)
insert into tb select 1, '张三' , 103, 20 , 720
insert into tb select 1 , '张三' , 104 , 20 , 280
insert into tb select 1 , '张三' , 106 , 20 , 4650
insert into tb select 2 , '李四' , 102 , 40 , 100
insert into tb select 2 , '李四' , 103 , 40 , 200
insert into tb select 2 , '李四' , 104 , 40 , 300
insert into tb select 2 , '李四', 106 , 40, 600

declare @sql varchar(8000)
set @sql=''
select @sql=@sql+',sum(case when 类型='+cast(类型 as varchar)+' then 数量 else 0 end)
as ['+cast(类型 as varchar)+'数量]'
from (select distinct 类型 from tb) a

exec ('select 户号,户名'+@sql+' from tb group by 户号,户名')

drop table tb

/*
户号 户名 102数量 103数量 104数量 106数量
----------- -------------------- ----------- ----------- ----------- -----------
2 李四 100 200 300 600
1 张三 0 720 280 4650
*/
kk19840210 2008-01-14
  • 打赏
  • 举报
回复

如果类型固定
select 户号,户名,[102数量]=sum(case when 类型='102' then 数量 else 0 end)
,[103数量]=sum(case when 类型='103' then 数量 else 0 end)
,[104数量]=sum(case when 类型='104' then 数量 else 0 end)
,[106数量]=sum(case when 类型='106' then 数量 else 0 end)
group by 户号,户名
free1879 2008-01-14
  • 打赏
  • 举报
回复
1. 动态SQL case when
2.pivot unpivot

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧