恐怕没那么容易写成通用的SQL语句,给你一个SQL Server的:
---------------------------------------------------------------------
--生成测试数据
create table 授课表1(id int,老师姓名 varchar(20),所带学生档案号 int,[团体/个人] varchar(20))
insert into 授课表1 select 2 ,'王二',1 ,'团体'
insert into 授课表1 select 3 ,'王二',2 ,'团体'
insert into 授课表1 select 4 ,'王二',3 ,'团体'
insert into 授课表1 select 5 ,'王二',4 ,'团体'
insert into 授课表1 select 6 ,'王二',5 ,'个人' 
insert into 授课表1 select 7 ,'王二',6 ,'个人' 
insert into 授课表1 select 8 ,'王二',7 ,'个人' 
insert into 授课表1 select 9 ,'王二',8 ,'个人' 
insert into 授课表1 select 10,'李四',12,'个人' create table 授课表2(授课表1id int,所学课目 varchar(20),[所需金额] int)
insert into 授课表2 select 2 ,'数学',10
insert into 授课表2 select 3 ,'数学',10
insert into 授课表2 select 4 ,'数学',10
insert into 授课表2 select 5 ,'数学',10
insert into 授课表2 select 6 ,'英文',10
insert into 授课表2 select 7 ,'英文',10
insert into 授课表2 select 8 ,'中文',10
insert into 授课表2 select 9 ,'中文',10
insert into 授课表2 select 10,'中文',10
insert into 授课表2 select 10,'英文',10
insert into 授课表2 select 10,'数学',10
--执行交叉表查询
declare @s varchar(8000),@str1 varchar(4000),@str2 varchar(4000)
set @str1 = ''
set @str2 = ''select
    @str1 = @str1 + ',['+所学课目+']=sum(case 所学课目 when '''+所学课目+''' then 1       else 0 end)',
    @str2 = @str2 + ',['+所学课目+']=sum(case 所学课目 when '''+所学课目+''' then 所需金额 else 0 end)'
from
    授课表2
group by
    所学课目set @s =  ' select a.老师姓名'
         +',小计=count(distinct a.id)'
         +',团体=count(distinct case a.[团体/个人] when ''团体'' then a.id end)'
         +',个人=count(distinct case a.[团体/个人] when ''个人'' then a.id end)'
         +',小计=sum(1)'+@str1+
         +',小计=sum(b.所需金额)'+@str2+
         +' from 授课表1 a,授课表2 b where a.id=b.授课表1id group by 老师姓名'
         +' union'
         +' select '' 合计'''
         +',(select count(distinct id) from 授课表1)'
         +',(select count(distinct id) from 授课表1 where [团体/个人]=''团体'')'
         +',(select count(distinct id) from 授课表1 where [团体/个人]=''个人'')'
         +',小计=sum(1)'+@str1+
         +',小计=sum(b.所需金额)'+@str2+
         +' from 授课表1 a,授课表2 b where a.id=b.授课表1id order by 老师姓名 desc'exec(@s)--输出结果
/*
老师姓名  小计  团体  个人  小计  英文  数学  中文  小计  英文  数学  中文
--------  ----  ----  ----  ----  ----  ----  ----  ----  ----  ----  ----
王二      8     4     4     8     2     4     2     80    20    40    20   
李四      1           1     3     1     1     1     30    10    10    10
 合计     9     4     5     11    3     5     3     110   30    50    30 
*/

解决方案 »

  1.   

    没有优化,代码比较长,逻辑上比较简单:
    create table [授课表1]
    (
      id int,
      [老师姓名] varchar(10),
      [所带学生档案号] int,
      [团体/个人] varchar(10)
    )
    create table [授课表2]
    (
      [授课表1id] int,
      [所学课目] varchar(10),
      [所需金额(元/小时)] int
    )
    insert [授课表1]
    select 2,'王二',1,'团体' union all 
    select 3,'王二',2,'团体' union all 
    select 4,'王二',3,'团体' union all 
    select 5,'王二',4,'团体' union all 
    select 6,'王二',5,'个人' union all 
    select 7,'王二',6,'个人' union all 
    select 8,'王二',7,'个人' union all 
    select 9,'王二',8,'个人' union all 
    select 10,'李四',12,'个人' 
    insert [授课表2]
    select 2,'数学',10 union all 
    select 3,'数学',10 union all 
    select 4,'数学',10 union all 
    select 5,'数学',10 union all 
    select 6,'英文',10 union all 
    select 7,'英文',10 union all 
    select 8,'中文',10 union all 
    select 9,'中文',10 union all 
    select 10,'中文',10 union all 
    select 10,'英文',10 union all 
    select 10,'数学',10 --查询
    select A.[老师姓名]
           ,count(distinct B.[授课表1id]) as '小计'
           ,sum(case when A.[团体/个人]='团体' and B.status=1 then 1 else 0 end) as '团体'
           ,sum(case when A.[团体/个人]='个人' and B.status=1 then 1 else 0 end) as '个人'
           ,count(B.[所学课目])  as '小计'
           ,sum(case when B.[所学课目]='英文' then 1 else 0 end) as '英文'
           ,sum(case when B.[所学课目]='数学' then 1 else 0 end) as '数学'
           ,sum(case when B.[所学课目]='中文' then 1 else 0 end) as '中文'
           ,sum(B.[所需金额(元/小时)]) as '小计'
           ,sum(case when B.[所学课目]='英文' then B.[所需金额(元/小时)] else 0 end) as '英文'
           ,sum(case when B.[所学课目]='数学' then B.[所需金额(元/小时)] else 0 end) as '数学'
           ,sum(case when B.[所学课目]='中文' then B.[所需金额(元/小时)] else 0 end) as '中文'     from [授课表1] A
    join (      select top 100 percent *
                 ,(case when not exists(select 1 from [授课表2] where [授课表1id]=t.[授课表1id] and [所学课目]<t.[所学课目])
                        then 1
                        else 0
                   end
                  ) as 'status'
          from [授课表2] t
          order by [所学课目]
         ) B on A.id=B.[授课表1id]
    group by A.[老师姓名]
    union 
    select '合计'
           ,count(distinct B.[授课表1id]) as '小计'
           ,sum(case when A.[团体/个人]='团体' and B.status=1 then 1 else 0 end) as '团体'
           ,sum(case when A.[团体/个人]='个人' and B.status=1 then 1 else 0 end) as '个人'
           ,count(B.[所学课目])  as '小计'
           ,sum(case when B.[所学课目]='英文' then 1 else 0 end) as '英文'
           ,sum(case when B.[所学课目]='数学' then 1 else 0 end) as '数学'
           ,sum(case when B.[所学课目]='中文' then 1 else 0 end) as '中文'
           ,sum(B.[所需金额(元/小时)]) as '小计'
           ,sum(case when B.[所学课目]='英文' then B.[所需金额(元/小时)] else 0 end) as '英文'
           ,sum(case when B.[所学课目]='数学' then B.[所需金额(元/小时)] else 0 end) as '数学'
           ,sum(case when B.[所学课目]='中文' then B.[所需金额(元/小时)] else 0 end) as '中文'     from [授课表1] A
    join (      select top 100 percent *
                 ,(case when not exists(select 1 from [授课表2] where [授课表1id]=t.[授课表1id] and [所学课目]<t.[所学课目])
                        then 1
                        else 0
                   end
                  ) as 'status'
          from [授课表2] t
          order by [所学课目]
         ) B on A.id=B.[授课表1id]--结果
    /*
    老师姓名       小计          团体          个人          小计          英文          数学          中文          小计          英文          数学          中文          
    ---------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- 
    合计         9.00        4.00        5.00        11.00       3.00        5.00        3.00        110.00      30.00       50.00       30.00
    李四         1.00        .00         1.00        3.00        1.00        1.00        1.00        30.00       10.00       10.00       10.00
    王二         8.00        4.00        4.00        8.00        2.00        4.00        2.00        80.00       20.00       40.00       20.00(所影响的行数为 3 行)
    */