行列转换是怎么回事?
一般用在什么地方?
有什么作用?
希望可以代码演示 并详细说明下? 谢谢

解决方案 »

  1.   

    参考大乌龟的吧./*
    标题:普通行列转换(version 2.0)
    作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
    时间:2008-03-09
    地点:广东深圳
    说明:普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法,version 2.0增加sql server 2005的有关写法。问题:假设有张学生成绩表(tb)如下:
    姓名 课程 分数
    张三 语文 74
    张三 数学 83
    张三 物理 93
    李四 语文 74
    李四 数学 84
    李四 物理 94
    想变成(得到如下结果): 
    姓名 语文 数学 物理 
    ---- ---- ---- ----
    李四 74   84   94
    张三 74   83   93
    -------------------
    */create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
    insert into tb values('张三' , '语文' , 74)
    insert into tb values('张三' , '数学' , 83)
    insert into tb values('张三' , '物理' , 93)
    insert into tb values('李四' , '语文' , 74)
    insert into tb values('李四' , '数学' , 84)
    insert into tb values('李四' , '物理' , 94)
    go--SQL SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)
    select 姓名 as 姓名 ,
      max(case 课程 when '语文' then 分数 else 0 end) 语文,
      max(case 课程 when '数学' then 分数 else 0 end) 数学,
      max(case 课程 when '物理' then 分数 else 0 end) 物理
    from tb
    group by 姓名--SQL SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
    declare @sql varchar(8000)
    set @sql = 'select 姓名 '
    select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'
    from (select distinct 课程 from tb) as a
    set @sql = @sql + ' from tb group by 姓名'
    exec(@sql) --SQL SERVER 2005 静态SQL。
    select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b--SQL SERVER 2005 动态SQL。
    declare @sql varchar(8000)
    select @sql = isnull(@sql + '],[' , '') + 课程 from tb group by 课程
    set @sql = '[' + @sql + ']'
    exec ('select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b')---------------------------------/*
    问题:在上述结果的基础上加平均分,总分,得到如下结果:
    姓名 语文 数学 物理 平均分 总分 
    ---- ---- ---- ---- ------ ----
    李四 74   84   94   84.00  252
    张三 74   83   93   83.33  250
    */--SQL SERVER 2000 静态SQL。
    select 姓名 姓名,
      max(case 课程 when '语文' then 分数 else 0 end) 语文,
      max(case 课程 when '数学' then 分数 else 0 end) 数学,
      max(case 课程 when '物理' then 分数 else 0 end) 物理,
      cast(avg(分数*1.0) as decimal(18,2)) 平均分,
      sum(分数) 总分
    from tb
    group by 姓名--SQL SERVER 2000 动态SQL。
    declare @sql varchar(8000)
    set @sql = 'select 姓名 '
    select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'
    from (select distinct 课程 from tb) as a
    set @sql = @sql + ' , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名'
    exec(@sql) --SQL SERVER 2005 静态SQL。
    select m.* , n.平均分 , n.总分 from
    (select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b) m,
    (select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n
    where m.姓名 = n.姓名--SQL SERVER 2005 动态SQL。
    declare @sql varchar(8000)
    select @sql = isnull(@sql + ',' , '') + 课程 from tb group by 课程
    exec ('select m.* , n.平均分 , n.总分 from
    (select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b) m , 
    (select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n
    where m.姓名 = n.姓名')drop table tb    ------------------
    ------------------/*
    问题:如果上述两表互相换一下:即表结构和数据为:
    姓名 语文 数学 物理
    张三 74  83  93
    李四 74  84  94
    想变成(得到如下结果): 
    姓名 课程 分数 
    ---- ---- ----
    李四 语文 74
    李四 数学 84
    李四 物理 94
    张三 语文 74
    张三 数学 83
    张三 物理 93
    --------------
    */create table tb(姓名 varchar(10) , 语文 int , 数学 int , 物理 int)
    insert into tb values('张三',74,83,93)
    insert into tb values('李四',74,84,94)
    go--SQL SERVER 2000 静态SQL。
    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--SQL SERVER 2000 动态SQL。
    --调用系统表动态生态。
    declare @sql varchar(8000)
    select @sql = isnull(@sql + ' union all ' , '' ) + ' select 姓名 , [课程] = ' + quotename(Name , '''') + ' , [分数] = ' + quotename(Name) + ' from tb'
    from syscolumns 
    where name! = N'姓名' and ID = object_id('tb') --表名tb,不包含列名为姓名的其它列
    order by colid asc
    exec(@sql + ' order by 姓名 ')--SQL SERVER 2005 动态SQL。
    select 姓名 , 课程 , 分数 from tb unpivot (分数 for 课程 in([语文] , [数学] , [物理])) t--SQL SERVER 2005 动态SQL,同SQL SERVER 2000 动态SQL。--------------------
    /*
    问题:在上述的结果上加个平均分,总分,得到如下结果:
    姓名 课程   分数
    ---- ------ ------
    李四 语文   74.00
    李四 数学   84.00
    李四 物理   94.00
    李四 平均分 84.00
    李四 总分   252.00
    张三 语文   74.00
    张三 数学   83.00
    张三 物理   93.00
    张三 平均分 83.33
    张三 总分   250.00
    ------------------
    */select * from
    (
     select 姓名 as 姓名 , 课程 = '语文' , 分数 = 语文 from tb 
     union all
     select 姓名 as 姓名 , 课程 = '数学' , 分数 = 数学 from tb
     union all
     select 姓名 as 姓名 , 课程 = '物理' , 分数 = 物理 from tb
     union all
     select 姓名 as 姓名 , 课程 = '平均分' , 分数 = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb
     union all
     select 姓名 as 姓名 , 课程 = '总分' , 分数 = 语文 + 数学 + 物理 from tb
    ) t
    order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 enddrop table tb
      

  2.   


    将表数据旋转90度(2007-11-19于海南三亚)将下表数据:
    A                    b           c           d           e           
    -------------------- ----------- ----------- ----------- ----------- 
    x                    1           2           3           4
    y                    5           6           7           8
    z                    9           10          11          12转化成如下结果:
    a                    x          y          z          
    -------------------- ---------- ---------- ---------- 
    b                    1          5          9
    c                    2          6          10
    d                    3          7          11
    e                    4          8          12*/--生成测试数据
    create table #test1(A varchar(20),b int,c int,d int,e int)
    insert into #test1 select 'x',1,2 ,3 ,4
    insert into #test1 select 'y',5,6 ,7 ,8
    insert into #test1 select 'z',9,10,11,12
    go
    select * from #test1
    select a,max(x) as x,max(y) as y,max(z) as z from (
    select a='b',
           x=case when a='x' then b else 0 end,
           y=case when a='y' then b else 0 end,
           z=case when a='z' then b else 0 end
    from #test1
    union all
    select a='c',
           x=case when a='x' then c else 0 end,
           y=case when a='y' then c else 0 end,
           z=case when a='z' then c else 0 end
    from #test1
    union all
    select a='d',
           x=case when a='x' then d else 0 end,
           y=case when a='y' then d else 0 end,
           z=case when a='z' then d else 0 end
    from #test1
    union all
    select a='e',
           x=case when a='x' then e else 0 end,
           y=case when a='y' then e else 0 end,
           z=case when a='z' then e else 0 end
    from #test1) t
    group by a
     
    --生成中间数据表
    declare @s varchar(8000)
    set @s = 'create table test2(a varchar(20)'
    select @s = @s + ',' + A + ' varchar(10)' from test1
    set @s = @s + ')'
    exec(@s)
    print @s
    --借助中间表实现行列转换
    declare @name varchar(20)declare t_cursor cursor for 
    select name from syscolumns 
    where id=object_id('test1') and colid > 1 order by colidopen t_cursorfetch next from t_cursor into @namewhile @@fetch_status = 0
    begin
        exec('select ' + @name + ' as t into test3 from test1')
        set @s='insert into test2 select ''' + @name + ''''
        select @s = @s + ',''' + rtrim(t) + '''' from test3
        exec(@s)
        exec('drop table test3')
        fetch next from t_cursor into @name
    end
    close t_cursor
    deallocate t_cursor--查看行列互换处理结果
    select * from test1
    select * from test2--删除表
    drop table test1
    drop table test2
    ----------------------------------------------------------------------------
    /*固定的写法:*/
    select t1.* , t2.y , t3.z from
    (select a = 'b' , x = b from #test1 where a = 'x') t1, 
    (select a = 'b' , y = b from #test1 where a = 'y') t2,
    (select a = 'b' , z = b from #test1 where a = 'z') t3
    where t1.a = t2.a and t1.a = t2.a
    union all
    select t1.* , t2.y , t3.z from
    (select a = 'c' , x = c from #test1 where a = 'x') t1, 
    (select a = 'c' , y = c from #test1 where a = 'y') t2,
    (select a = 'c' , z = c from #test1 where a = 'z') t3
    where t1.a = t2.a and t1.a = t2.a
    union all
    select t1.* , t2.y , t3.z from
    (select a = 'd' , x = d from #test1 where a = 'x') t1, 
    (select a = 'd' , y = d from #test1 where a = 'y') t2,
    (select a = 'd' , z = d from #test1 where a = 'z') t3
    where t1.a = t2.a and t1.a = t2.a
    union all
    select t1.* , t2.y , t3.z from
    (select a = 'e' , x = e from #test1 where a = 'x') t1, 
    (select a = 'e' , y = e from #test1 where a = 'y') t2,
    (select a = 'e' , z = e from #test1 where a = 'z') t3
    where t1.a = t2.a and t1.a = t2.a----------------------------------------------------------------------------
    /*
    表tb,数据如下:
    项目种类  业绩  提成
    洗吹类  200   10
    外卖      100   5
    合计      300   15
    转换成:
    项目种类  洗吹类  外卖  合计
    业绩      200     100   300
    提成      10      5     15
    */create table tb
    (
      项目种类 varchar(10),
      业绩     int,
      提成     int
    )insert into tb(项目种类,业绩,提成) values('洗吹类',200,10)
    insert into tb(项目种类,业绩,提成) values('外卖'  ,100,5)
    insert into tb(项目种类,业绩,提成) values('合计'  ,300,15)
    goselect 项目种类,sum(洗吹类) as 洗吹类 , sum(外卖) as 外卖 , sum(合计) as 合计 from
    (
      select 项目种类 = '业绩',
             洗吹类   = case when 项目种类 = '洗吹类' then 业绩 else 0 end,
             外卖     = case when 项目种类 = '外卖'   then 业绩 else 0 end,
             合计     = case when 项目种类 = '合计'   then 业绩 else 0 end
      from tb
    union all
      select 项目种类 = '提成' ,
             洗吹类   = case when 项目种类 = '洗吹类' then 提成 else 0 end,
             外卖     = case when 项目种类 = '外卖'   then 提成 else 0 end,
             合计     = case when 项目种类 = '合计'   then 提成 else 0 end
      from tb
    ) m
    group by 项目种类
    order by 项目种类 descdrop table tb/*
    项目种类 洗吹类      外卖        合计          
    -------- ----------- ----------- ----------- 
    业绩     200         100         300
    提成     10          5           15(所影响的行数为 2 行)
    */--------------------------------------------------------------------------
    /*
    数据库中tb表格如下
     
    月份    工资   福利  奖金
    1月     100    200   300
    2月     110    210   310
    3月     120    220   320
    4月     130    230   330我想得到的结果是项目   1月    2月  3月  4月
    工资   100    110  120  130
    福利   200    210  220  230
    奖金   300    310  320  330就是说完全把表格的行列颠倒,有点像那种旋转矩阵,请问如何用sql 语句实现?
    */if exists (select * from dbo.sysobjects
    where id = object_id(N'[dbo].[p_zj]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[p_zj]
    GO
    /*--行列互换的通用存储过程(原著:邹建):将指定的表,按指定的字段进行行列互换*/create proc p_zj
           @tbname sysname, --要处理的表名
           @fdname sysname, --做为转换的列名
           @new_fdname sysname='' --为转换后的列指定列名
    as
    declare @s1 varchar(8000) , @s2 varchar(8000),
            @s3 varchar(8000) , @s4 varchar(8000),
            @s5 varchar(8000) , @i varchar(10)
    select @s1 = '' , @s2 = '' , @s3 = '' , @s4 = '' , @s5 = '' , @i = '0'
    select @s1 = @s1 + ',@' + @i + ' varchar(8000)',
           @s2 = @s2 + ',@' + @i + '=''' + case isnull(@new_fdname , '') when '' then ''
           else @new_fdname + '=' end + '''''' + name + '''''''',
           @s3 = @s3 + 'select @' + @i + '=@' + @i + '+'',['' + [' + @fdname + 
           ']+'']=''+cast([' + name + '] as varchar) from [' + @tbname + ']',
           @s4 = @s4 + ',@' + @i + '=''select ''+@' + @i,
           @s5 = @s5 + '+'' union all ''+@' + @i,
           @i=cast(@i as int)+1
    from syscolumns
    where object_id(@tbname)=id and name<>@fdnameselect @s1=substring(@s1,2,8000),
           @s2=substring(@s2,2,8000),
           @s4=substring(@s4,2,8000),
           @s5=substring(@s5,16,8000)
    exec('declare ' + @s1 + 'select ' + @s2 + @s3 + 'select ' + @s4 + '
    exec(' + @s5 + ')')
    go--用上面的存储过程测试:create table Test(月份 varchar(4), 工资 int, 福利 int, 奖金 int)
    insert Test 
    select '1月',100,200,300 union all
    select '2月',110,210,310 union all
    select '3月',120,220,320 union all
    select '4月',130,230,330
    goexec p_zj 'Test', '月份' , '项目'drop table Test
    drop proc p_zj/*
    项目   1月         2月         3月         4月          
    ---- ----------- ----------- ----------- ----------- 
    福利   200         210         220         230
    工资   100         110         120         130
    奖金   300         310         320         330(所影响的行数为 3 行)
    *//*
    静态写法(SQL2005)
    */
    --测试环境
    create table Test(月份 varchar(4), 工资 int, 福利 int, 奖金 int)
    insert Test
    select '1月',100,200,300 union all
    select '2月',110,210,310 union all
    select '3月',120,220,320 union all
    select '4月',130,230,330
    go
    --测试语句
    SELECT * FROM 
    (
      SELECT 考核月份,月份,金额 FROM 
         (SELECT 月份, 工资, 福利, 奖金 FROM Test) p
      UNPIVOT
         (金额 FOR 考核月份 IN (工资, 福利, 奖金))AS unpvt
    ) T
    PIVOT
    (MAX(金额)  FOR 月份 in ([1月],[2月],[3月],[4月]))AS pt--测试结果/*
    考核月份  1月     2月      3月     4月
    -------  -----  -----   ------  -------
    福利200210220230
    工资100110120130
    奖金300310320330
    */--删除环境
    Drop table Test
      

  3.   

    --行列互转
    /******************************************************************************************************************************************************
    以学生成绩为例子,比较形象易懂整理人:中国风(Roy)日期:2008.06.06
    ******************************************************************************************************************************************************/--1、行互列
    --> --> (Roy)生成測試數據
     
    if not object_id('Class') is null
        drop table Class
    Go
    Create table Class([Student] nvarchar(2),[Course] nvarchar(2),[Score] int)
    Insert Class
    select N'张三',N'语文',78 union all
    select N'张三',N'数学',87 union all
    select N'张三',N'英语',82 union all
    select N'张三',N'物理',90 union all
    select N'李四',N'语文',65 union all
    select N'李四',N'数学',77 union all
    select N'李四',N'英语',65 union all
    select 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]
    exec('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]
    exec('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),
        [总成绩]=sum([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、列转行
    --> --> (Roy)生成測試數據
     
    if not object_id('Class') is null
        drop table Class
    Go
    Create table Class([Student] nvarchar(2),[数学] int,[物理] int,[英语] int,[语文] int)
    Insert Class
    select N'李四',77,85,65,65 union all
    select N'张三',87,90,82,78
    Go--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 Colid
    exec('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 Colid
    exec('select Student,[Course],[Score] from Class unpivot ([Score] for [Course] in('+@s+'))b')go
    select 
        Student,[Course],[Score] 
    from 
        Class 
    unpivot 
        ([Score] for [Course] in([数学],[物理],[英语],[语文]))b生成格式:
    /*
    Student Course Score
    ------- ------- -----------
    李四      数学      77
    李四      物理      85
    李四      英语      65
    李四      语文      65
    张三      数学      87
    张三      物理      90
    张三      英语      82
    张三      语文      78(8 行受影响)
    */
      

  4.   

    /*
    按月进行行列转换并加合计(2007-11-19于海南三亚)例如有表tb某些人每月消费数据如下:
    id data month
    001 11 1
    001 12 2
    001 13 3
    001 14 4
    001 15 5
    001 16 6
    001 17 7
    001 18 8
    001 19 9
    001 110 10
    001 111 11
    001 112 12
    002 21 1
    002 22 2
    002 23 3
    002 24 4
    002 25 5
    002 26 6
    002 27 7
    002 28 8
    002 29 9
    002 210 10
    002 211 11
    002 212 12
    要实现如下结果: 
    人员 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
    001  11  12  13  14  15  16  17  18  19  110  111  112
    002  21  22  23  24  25   26 27  28  29  210  211  212
    */create table tb
    (
      id    char(3),
      data  int,
      month int
    )
    insert into tb(id,data,month) values('001',11,1)
    insert into tb(id,data,month) values('001',12,2)
    insert into tb(id,data,month) values('001',13,3)
    insert into tb(id,data,month) values('001',14,4)
    insert into tb(id,data,month) values('001',15,5)
    insert into tb(id,data,month) values('001',16,6)
    insert into tb(id,data,month) values('001',17,7)
    insert into tb(id,data,month) values('001',18,8)
    insert into tb(id,data,month) values('001',19,9)
    insert into tb(id,data,month) values('001',110,10)
    insert into tb(id,data,month) values('001',111,11)
    insert into tb(id,data,month) values('001',112,12)
    insert into tb(id,data,month) values('002',21,1)
    insert into tb(id,data,month) values('002',22,2)
    insert into tb(id,data,month) values('002',23,3)
    insert into tb(id,data,month) values('002',24,4)
    insert into tb(id,data,month) values('002',25,5)
    insert into tb(id,data,month) values('002',26,6)
    insert into tb(id,data,month) values('002',27,7)
    insert into tb(id,data,month) values('002',28,8)
    insert into tb(id,data,month) values('002',29,9)
    insert into tb(id,data,month) values('002',210,10)
    insert into tb(id,data,month) values('002',211,11)
    insert into tb(id,data,month) values('002',212,12)
    goSELECT id as '人员' , 
      SUM(CASE month WHEN 1 THEN data ELSE 0 END) AS '1月' ,
      SUM(CASE month WHEN 2 THEN data ELSE 0 END) AS '2月' ,
      SUM(CASE month WHEN 3 THEN data ELSE 0 END) AS '3月' ,
      SUM(CASE month WHEN 4 THEN data ELSE 0 END) AS '4月' ,
      SUM(CASE month WHEN 5 THEN data ELSE 0 END) AS '5月' ,
      SUM(CASE month WHEN 6 THEN data ELSE 0 END) AS '6月' ,
      SUM(CASE month WHEN 7 THEN data ELSE 0 END) AS '7月' ,
      SUM(CASE month WHEN 8 THEN data ELSE 0 END) AS '8月' ,
      SUM(CASE month WHEN 9 THEN data ELSE 0 END) AS '9月' ,
      SUM(CASE month WHEN 10 THEN data ELSE 0 END) AS '10月' ,
      SUM(CASE month WHEN 11 THEN data ELSE 0 END) AS '11月' ,
      SUM(CASE month WHEN 12 THEN data ELSE 0 END) AS '12月' 
    FROM tb
    GROUP BY ID drop table tb/*
    人员 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
    ---- --- --- --- --- --- --- --- --- --- ---- ---- ----
    001  11  12  13  14  15  16  17  18  19  110  111  112
    002  21  22  23  24  25  26  27  28  29  210  211  212(所影响的行数为 2 行)
    */--------------------------------------------------------------
    /*
    合计每个人每年的数据
    人员 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 合计
    001  11  12  13  14  15  16  17  18  19  110  111  112  468
    002  21  22  23  24  25   26 27  28  29  210  211  212  858
    */SELECT id as '人员' , 
    SUM(CASE month WHEN 1 THEN data ELSE 0 END) AS '1月' ,
    SUM(CASE month WHEN 2 THEN data ELSE 0 END) AS '2月' ,
    SUM(CASE month WHEN 3 THEN data ELSE 0 END) AS '3月' ,
    SUM(CASE month WHEN 4 THEN data ELSE 0 END) AS '4月' ,
    SUM(CASE month WHEN 5 THEN data ELSE 0 END) AS '5月' ,
    SUM(CASE month WHEN 6 THEN data ELSE 0 END) AS '6月' ,
    SUM(CASE month WHEN 7 THEN data ELSE 0 END) AS '7月' ,
    SUM(CASE month WHEN 8 THEN data ELSE 0 END) AS '8月' ,
    SUM(CASE month WHEN 9 THEN data ELSE 0 END) AS '9月' ,
    SUM(CASE month WHEN 10 THEN data ELSE 0 END) AS '10月' ,
    SUM(CASE month WHEN 11 THEN data ELSE 0 END) AS '11月' ,
    SUM(CASE month WHEN 12 THEN data ELSE 0 END) AS '12月' ,
    SUM(data) as '合计'
    FROM tb
    GROUP BY ID /*
    人员 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 合计
    ---- --- --- --- --- --- --- --- --- --- ---- ---- ---- ----
    001  11  12  13  14  15  16  17  18  19  110  111  112  468
    002  21  22  23  24  25  26  27  28  29  210  211  212  858
    */