问题:假设有张学生成绩表(tb)如下:
姓名 课程 第一次分数 第二次分数
张三 语文   74         81
张三 数学   83         93
张三 物理   93         100
李四 语文   74         89
李四 数学   84         86
李四 物理   94         96想变成(得到如下结果): 
姓名 语文第一次  语文第二次  语文总分   数学第一次  数学第二次   数学总分    物理第一次  物理第二次 物理总分  总累计第一次   总累计第二次
---- ---- ---- ----
李四 74           89          163        84            ..                        94           ..
张三 74           81          155        83            ..                        93           ..
-------------------课程不要写死.

解决方案 »

  1.   

    ---测试数据---
    if object_id('[tb]') is not null drop table [tb]
    go
    create table [tb]([姓名] varchar(4),[课程] varchar(4),[第一次分数] int,[第二次分数] int)
    insert [tb]
    select '张三','语文',74,81 union all
    select '张三','数学',83,93 union all
    select '张三','物理',93,100 union all
    select '李四','语文',74,89 union all
    select '李四','数学',84,86 union all
    select '李四','物理',94,96
     
    ---查询---
    declare @sql varchar(8000)
    select
      @sql=isnull(@sql+',','')
      +'max(case when 课程='''+课程+''' then 第一次分数 else 0 end) as ['+课程+'第一次分数],'
      +'max(case when 课程='''+课程+''' then 第二次分数 else 0 end) as ['+课程+'第二次分数],'
      +'max(case when 课程='''+课程+''' then 第一次分数+第二次分数 else 0 end) as ['+课程+'总分]'
    from
    (select distinct 课程 from tb) texec ('select 姓名,'+@sql+' from tb group by 姓名')
      ---结果---
    姓名   数学第一次分数     数学第二次分数     数学总分        物理第一次分数     物理第二次分数     物理总分        语文第一次分数     语文第二次分数     语文总分
    ---- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
    李四   84          86          170         94          96          190         74          89          163
    张三   83          93          176         93          100         193         74          81          155(2 行受影响)
      

  2.   

    固定列数的行列转换

    student subject grade
    --------- ---------- --------
    student1 语文 80
    student1 数学 70
    student1 英语 60
    student2 语文 90
    student2 数学 80
    student2 英语 100
    ……
    转换为
    语文 数学 英语
    student1 80 70 60
    student2 90 80 100
    ……
    语句如下:select student,  
    sum(decode(subject,'语文', grade,null)) "语文",
    sum(decode(subject,'数学', grade,null)) "数学",
    sum(decode(subject,'英语', grade,null)) "英语"
    from table
    group by student;
      

  3.   

    增加累计
    ---查询---
    declare @sql varchar(8000)
    select
      @sql=isnull(@sql+',','')
      +'max(case when 课程='''+课程+''' then 第一次分数 else 0 end) as ['+课程+'第一次分数],'
      +'max(case when 课程='''+课程+''' then 第二次分数 else 0 end) as ['+课程+'第二次分数],'
      +'max(case when 课程='''+课程+''' then 第一次分数+第二次分数 else 0 end) as ['+课程+'总分]'
    from
    (select distinct 课程 from tb) texec (
      'select 姓名,'
      +@sql
      +',sum(第一次分数) as [总累计第一次],sum(第二次分数) as [总累计第二次]'
      +'from tb group by 姓名'
    )
      ---结果---
    姓名   数学第一次分数     数学第二次分数     数学总分        物理第一次分数     物理第二次分数     物理总分        语文第一次分数     语文第二次分数     语文总分        总累计第一次      总累计第二次
    ---- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
    李四   84          86          170         94          96          190         74          89          163         252         271
    张三   83          93          176         93          100         193         74          81          155         250         274(2 行受影响)
      

  4.   


    IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]
    GO
    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--select *  from tb;select 姓名,[语文] as [语文],[数学] as [数学],[物理] as [物理] from tb
    pivot  (max(分数) for 课程 in ([语文],[数学],[物理])) pvt
      

  5.   

    ----------------------------------------------------------------
    -- Author  :fredrickhu(小F,向高手学习)
    -- Date    :2011-05-10 16:44:19
    -- Verstion:
    --      Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) 
    -- Jul  9 2008 14:43:34 
    -- Copyright (c) 1988-2008 Microsoft Corporation
    -- Enterprise Evaluation Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)
    --
    ----------------------------------------------------------------
    --> 测试数据:[tb]
    if object_id('[tb]') is not null drop table [tb]
    go 
    create table [tb]([姓名] varchar(4),[课程] varchar(4),[第一次分数] int,[第二次分数] int)
    insert [tb]
    select '张三','语文',74,81 union all
    select '张三','数学',83,93 union all
    select '张三','物理',93,100 union all
    select '李四','语文',74,89 union all
    select '李四','数学',84,86 union all
    select '李四','物理',94,96
    --------------开始查询--------------------------select
     姓名,
     max(case when 课程='数学' then 第一次分数 else 0 end) as [数学第一次分数],
     max(case when 课程='数学' then 第二次分数 else 0 end) as [数学第二次分数],
     max(case when 课程='数学' then 第一次分数+第二次分数 else 0 end) as [数学总分],
     max(case when 课程='物理' then 第一次分数 else 0 end) as [物理第一次分数],
     max(case when 课程='物理' then 第二次分数 else 0 end) as [物理第二次分数],
     max(case when 课程='物理' then 第一次分数+第二次分数 else 0 end) as [物理总分],
     max(case when 课程='语文' then 第一次分数 else 0 end) as [语文第一次分数],
     max(case when 课程='语文' then 第二次分数 else 0 end) as [语文第二次分数],
     max(case when 课程='语文' then 第一次分数+第二次分数 else 0 end) as [语文总分],
     sum(第一次分数) as [总累计第一次],sum(第二次分数) as [总累计第二次]
    from
     tb 
    group by
     姓名----------------结果----------------------------
    /* 姓名   数学第一次分数     数学第二次分数     数学总分        物理第一次分数     物理第二次分数     物理总分        语文第一次分数     语文第二次分数     语文总分        总累计第一次      总累计第二次
    ---- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
    李四   84          86          170         94          96          190         74          89          163         252         271
    张三   83          93          176         93          100         193         74          81          155         250         274(2 行受影响)
    */
      

  6.   

    ----------------------------------------------------------------
    -- Author  :fredrickhu(小F,向高手学习)
    -- Date    :2011-05-10 16:44:19
    -- Verstion:
    --      Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) 
    -- Jul  9 2008 14:43:34 
    -- Copyright (c) 1988-2008 Microsoft Corporation
    -- Enterprise Evaluation Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)
    --
    ----------------------------------------------------------------
    --> 测试数据:[tb]
    if object_id('[tb]') is not null drop table [tb]
    go 
    create table [tb]([姓名] varchar(4),[课程] varchar(4),[第一次分数] int,[第二次分数] int)
    insert [tb]
    select '张三','语文',74,81 union all
    select '张三','数学',83,93 union all
    select '张三','物理',93,100 union all
    select '李四','语文',74,89 union all
    select '李四','数学',84,86 union all
    select '李四','物理',94,96
    --------------开始查询--------------------------declare @sql varchar(8000)
    select
      @sql=isnull(@sql+',','')
      +'max(case when 课程='''+课程+''' then 第一次分数 else 0 end) as ['+课程+'第一次分数],'
      +'max(case when 课程='''+课程+''' then 第二次分数 else 0 end) as ['+课程+'第二次分数],'
      +'max(case when 课程='''+课程+''' then 第一次分数+第二次分数 else 0 end) as ['+课程+'总分]'
    from
    (select distinct 课程 from tb) texec ('select 姓名,'+@sql+',sum(第一次分数) as [总累计第一次],sum(第二次分数) as [总累计第二次]'+'from tb group by 姓名')
    ----------------结果----------------------------
    /* 姓名   数学第一次分数     数学第二次分数     数学总分        物理第一次分数     物理第二次分数     物理总分        语文第一次分数     语文第二次分数     语文总分        总累计第一次      总累计第二次
    ---- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
    李四   84          86          170         94          96          190         74          89          163         252         271
    张三   83          93          176         93          100         193         74          81          155         250         274(2 行受影响)
    */
      

  7.   

    也许可以从需求上考虑一下
    比如说:需求是为了将统计结果在页面上显示,这样完全可以把“行列互换”的事交给.net或者java等语言在客户端完全(借助使用arraylist等方法),效率上也许会更好一些
    另外,如果使用报表工具,就需要根据情况定了,有些报告工具,功能很单一,也许只能用SQL的方法在DB server上先完成结果处理了