首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

分组+行转列有关问题,DBA不在,压力很大

2012-09-10 
分组+行转列问题,DBA不在,压力很大SQL code -----建表数据CREATE TABLE [dbo].[stockinfo]([stockcode] [i

分组+行转列问题,DBA不在,压力很大

SQL code
 -----建表数据  CREATE TABLE [dbo].[stockinfo](    [stockcode] [int] NULL,    [yybid] [int] NULL,    [yybname] [nvarchar](50) NULL) ON [PRIMARY]  insert  into [master].[dbo].[stockinfo] values(1,1234,'hello')  insert  into [master].[dbo].[stockinfo] values(1,1235,'world')  insert  into [master].[dbo].[stockinfo] values(2,10000,'good')  insert  into [master].[dbo].[stockinfo] values(2,10001,'better')  insert  into [master].[dbo].[stockinfo] values(2,10002,'best')  insert  into [master].[dbo].[stockinfo] values(3,9527,'ios')  insert  into [master].[dbo].[stockinfo] values(3,9528,'android')  insert  into [master].[dbo].[stockinfo] values(3,9529,'firefoxos')  insert  into [master].[dbo].[stockinfo] values(3,9530,'meego')  insert  into [master].[dbo].[stockinfo] values(3,9531,'BlackBerry')  insert  into [master].[dbo].[stockinfo] values(4,3389,'port')


stockcode yybid yybname
1 1234hello
1 1235world
2 10000good
2 10001better
2 10002best
3 9527ios
3 9528android
3 9529firefoxos
3 9530meego
3 9531 BlackBerry
43389port

--这个是原表

--现在以stockcode分组
--需求为这样
stockcode yybid_1 yybid_2 yybid_3 yybid_4 yybid_5 yybname_1 yybname_2 yybname_3 yybname_4 yybname_5
1 1234 1235 null null null hello world null null null  
2 10000 10001 10002 null null good better best null null
3 9527 9528 9529 9530 9531 ios android firefoxos meego BlackBerry
4 3389 null null null null port null null null null  

本来也想用游标插入临时表来做,但是耗时确实很严重。
懂得大大,还望指点一二,先谢谢了!

[解决办法]
SQL code
--行列互转--摘自中国风博客,引用请标明内容来源--1、行换列if object_id('Class') is not  null    drop table ClassGoCreate table Class([Student] nvarchar(2),[Course] nvarchar(2),[Score] int)Insert Classselect N'张三',N'语文',78 union allselect N'张三',N'数学',87 union allselect N'张三',N'英语',82 union allselect N'张三',N'物理',90 union allselect N'李四',N'语文',65 union allselect N'李四',N'数学',77 union allselect N'李四',N'英语',65 union allselect N'李四',N'物理',85 Go--2000方法:--动态:declare @s nvarchar(4000)set @s=''Select @s=@s+','+quotename([Course])+'=max(case when [Course]='           +quotename([Course],'''')+' then [Score] else 0 end)'from     Class group by[Course]--select @sexec('select [Student]'+@s+' from Class group by [Student]')--生成静态:select     [Student],    [数学]=max(case when [Course]='数学' then [Score] else 0 end),    [物理]=max(case when [Course]='物理' then [Score] else 0 end),    [英语]=max(case when [Course]='英语' then [Score] else 0 end),    [语文]=max(case when [Course]='语文' then [Score] else 0 end) from     Class group by [Student]GO--动态:declare @s nvarchar(4000)Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course]select @sexec('select * from Class pivot (max([Score]) for [Course] in('+@s+'))b')--生成静态:select * from     Class pivot     (max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b--生成格式:/*Student 数学         物理         英语         语文------- ----------- ----------- ----------- -----------李四     77          85          65          65张三     87          90          82          78(2 行受影响)*/go--加上总成绩(学科平均分)--2000方法:--动态:declare @s nvarchar(4000)set @s=''Select @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+'then [Score] else 0 end)'from Class group by[Course]exec('select [Student]'+@s+',[总成绩]=sum([Score])  from Class group by [Student]')--加多一列(学科平均分用avg([Score]))生成动态:select     [Student],    [数学]=max(case when [Course]='数学' then [Score] else 0 end),    [物理]=max(case when [Course]='物理' then [Score] else 0 end),    [英语]=max(case when [Course]='英语' then [Score] else 0 end),    [语文]=max(case when [Course]='语文' then [Score] else 0 end),    [总成绩]=([Score]) --加多一列(学科平均分用avg([Score]))from     Class group by [Student]go--2005方法:动态:declare @s nvarchar(4000)Select  @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course] --isnull(@s+',','') 去掉字符串@s中第一个逗号exec('select [Student],'+@s+',[总成绩] from (select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a pivot (max([Score]) for [Course] in('+@s+'))b ')--生成静态:select     [Student],[数学],[物理],[英语],[语文],[总成绩] from     (select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a --平均分时用avg([Score])pivot     (max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b 生成格式:/*Student 数学         物理         英语         语文         总成绩------- ----------- ----------- ----------- ----------- -----------李四     77          85          65          65          292张三     87          90          82          78          337(2 行受影响)*/go--2、列转行 if not object_id('Class') is null    drop table ClassGoCreate table Class([Student] nvarchar(2),[数学] int,[物理] int,[英语] int,[语文] int)Insert Classselect N'李四',77,85,65,65 union allselect N'张三',87,90,82,78Go--2000:动态:declare @s nvarchar(4000)select @s=isnull(@s+' union all ','')+'select [Student],[Course]='+quotename(Name,'''')--isnull(@s+' union all ','') 去掉字符串@s中第一个union all+',[Score]='+quotename(Name)+' from Class'from syscolumns where ID=object_id('Class') and Name not in('Student')--排除不转换的列order by Colidexec('select * from ('+@s+')t order by [Student],[Course]')--增加一个排序生成静态:select * from (select [Student],[Course]='数学',[Score]=[数学] from Class union all select [Student],[Course]='物理',[Score]=[物理] from Class union all select [Student],[Course]='英语',[Score]=[英语] from Class union all select [Student],[Course]='语文',[Score]=[语文] from Class)t order by [Student],[Course]go--2005:动态:declare @s nvarchar(4000)select @s=isnull(@s+',','')+quotename(Name)from syscolumns where ID=object_id('Class') and Name not in('Student') order by Colidexec('select Student,[Course],[Score] from Class unpivot ([Score] for [Course] in('+@s+'))b')goselect     Student,[Course],[Score] from     Class unpivot     ([Score] for [Course] in([数学],[物理],[英语],[语文]))b生成格式:/*Student Course Score------- ------- -----------李四     数学     77李四     物理     85李四     英语     65李四     语文     65张三     数学     87张三     物理     90张三     英语     82张三     语文     78*/这类问题太多了,不想写,自己照着画画就出来了 


[解决办法]

SQL code
declare @sql varchar(max)declare @i int,@max intset @i=1select top 1 @max=count(yybid) from stockinfo group by stockcode order by count(yybid) descwhile @i<=@maxbegin    set @sql=isnull(@sql+',','')+' sum(case when rn='+ltrim(@i)+' then yybid else null end) yybid_'+ltrim(@i)    set @i=@i+1endset @i=1while @i<=@maxbegin    set @sql=isnull(@sql+',','')+' max(case when rn='+ltrim(@i)+' then yybname else null end) yybname'+ltrim(@i)    set @i=@i+1endset @sql='select stockcode,'+@sql+' from (select row_number() over(partition by stockcode order by stockcode) rn,*                                           from stockinfo)t group by stockcode'--print @sqlexec(@sql)--查询结果/*stockcode   yybid_1     yybid_2     yybid_3     yybid_4     yybid_5     yybname1                                           yybname2                                           yybname3                                           yybname4                                           yybname5----------- ----------- ----------- ----------- ----------- ----------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------------------------------------1           1234        1235        NULL        NULL        NULL        hello                                              world                                              NULL                                               NULL                                               NULL2           10000       10001       10002       NULL        NULL        good                                               better                                             best                                               NULL                                               NULL3           9527        9528        9529        9530        9531        ios                                                android                                            firefoxos                                          meego                                              BlackBerry4           3389        NULL        NULL        NULL        NULL        port                                               NULL      */ 

热点排行