表1
姓名 语文 数学
小名  120  130
小东  130  150
小明  110  150结果:
     小名 小东 小明
语文 120  130  110  
数学 130  150  150sql动态语句如何写?

解决方案 »

  1.   

    问题:假设有张学生成绩表(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) select 姓名 , [语文] , [数学] , [物理] from tb  
    pivot(max(分数) for 课程 in([语文] , [数学] , [物理])) pvt
      

  2.   

    http://blog.csdn.net/sinpoal/archive/2009/11/08/4785441.aspx
      

  3.   

    SELECT  subject, [小名],[小东],[小明] 
    FROM
    (
    SELECT  姓名,subject, value FROM #TP
    UNPIVOT(value for subject in([语文],[数学]))npvt
    )M 
    PIVOT(MAX(value) for 姓名 in([小名],[小东],[小明]))npvtsubject      小名          小东          小明
    ---------------- ----------- ----------- -----------
    数学         130         150         150
    语文         120         130         110(2 row(s) affected)
      

  4.   

    参考:
    /*
    标题:90度旋转行列转换之一
    作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
    时间:2010-05-08
    地点:重庆航天职业学院
    说明:无
    */
    /*
    数据库中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 语句实现?
    */
    /*--行列互换的通用存储过程(原著:邹建):将指定的表,按指定的字段进行行列互换*/
    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
    go--用上面的存储过程测试:
    exec p_zj 'Test', '月份' , '项目'drop table Test
    drop proc p_zj/*
    项目      1月      2月      3月      4月
    --------  ------   -------- -------- --------
    奖金      300      310      320      330
    工资      100      110      120      130
    福利      200      210      220      230(所影响的行数为 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
    goSELECT * FROM 
    (
      SELECT 考核月份,月份,金额 FROM 
         (SELECT 月份, 工资, 福利, 奖金 FROM Test) p
      UNPIVOT
         (金额 FOR 考核月份 IN (工资, 福利, 奖金))AS unpvt
    ) T
    PIVOT
    (MAX(金额) FOR 月份 in ([1月],[2月],[3月],[4月]))AS ptdrop table test/*
    项目      1月      2月      3月      4月
    --------  ------   -------- -------- --------
    奖金      300      310      320      330
    工资      100      110      120      130
    福利      200      210      220      230(3 行受影响)
    */