题目:有如下表
table1
月份    部门      业绩 
-------------------------------
一月份      01      10
一月份      02      10
一月份      03      5
二月份      02      8
二月份      04      9
三月份      03      8
为了得出下面的表,该怎样写查询语句?
部门         一月份    二月份    三月份
---------- ------ ------ ------
01         10     NULL   NULL
02         10     8      NULL
03         5      NULL   8
04         NULL   9      NULL
我自己试着写了一下,发现写了5、6个单独的select语句才能得出下表的结果(⊙﹏⊙b汗)
各位高手看看,有没有其他简单的方式完成这道题目?

解决方案 »

  1.   

    /*
    id salary
    -----------------
    1 2000-3000
    ----------------
    2 4000-5000
    */--生成测试数据:
    go
    if OBJECT_ID('tbl') is not null
    drop table tbl
    go
    create table tbl(
    id int,
    salary varchar(10)
    )
    go
    insert tbl
    select 1,'2001-3000' union all
    select 2,'3001-4000' union all
    select 3,'4001-5000' union all
    select 4,'5001-6000' union all
    select 5,'6001-7000'select *from tblselect *from tbl where LEFT(salary,CHARINDEX('-',salary)-1) between 2000 and 5000 
    and right(salary,CHARINDEX('-',salary)-1) between 2000 and 5000/*
    id salary
    1 2001-3000
    2 3001-4000
    3 4001-5000
    *//*
    现有表[Hong_Props],表中的字段如下:PropID PropGameType PropArrea type PropTime Props PropsCoun  1 1 1 金币 2012-02-11 道具A 24
      2 2 2 金币 2012-02-11 道具B 15
      3 1 1 绑定金币 2012-02-12 道具C 14
      4 2 1 金币 2012-02-12 道具D 2
      5 2 2 金币 2012-02-13 道具D 50
      6 1 2 绑定金币 2012-02-14 道具B 9
      7 2 2 绑定金币 2012-02-15 道具E 10
      8 1 1 金币 2012-02-15 道具A 20
       
       
    先我要得到的查询效果为:  日期 道具A 道具B 道具C 道具D 道具E 累计
    2012-02-11 24 15 0 0 0 39  
    2012-02-12 0 0 14 2 0 16
    2012-02-13 0 0 0 50 0 50  
    2012-02-14 0 9 0 0 10 19
    2012-02-15 20 0 0 0 10 30
    */--生成测试数据:
    go
    if OBJECT_ID('Hong_Props')is not null
    drop table Hong_Props
    go
    create table Hong_Props(
    PropID int,
    PropGameType int,
    PropArrea int,
    PropTime date,
    Props varchar(20),
    PropsCoun int
    )
    go
    insert Hong_Props
    select 1 ,1 ,1 ,'2012-02-11' ,'道具A' ,24 union all
    select 2 ,2 ,2 ,'2012-02-11' ,'道具B' ,15 union all
    select 3 ,1 ,1 ,'2012-02-12' ,'道具C' ,14 union all
    select 4 ,2 ,1 ,'2012-02-12' ,'道具D' ,2 union all
    select 5 ,2 ,2 ,'2012-02-13' ,'道具D' ,50 union all
    select 6 ,1 ,2 ,'2012-02-14' ,'道具B' ,9 union all
    select 7 ,2 ,2 ,'2012-02-15' ,'道具E' ,10 union all
    select 8 ,1 ,1 ,'2012-02-15' ,'道具A' ,20declare @str varchar(1000)
    set @str=''
    select @str=@str+','+Props+
    '=max(case when Props='+quotename(Props,'''')+' then PropsCoun else 0 end)' 
    from Hong_Props
    group by Props
    --print @str
    select @str='select PropTime'+@str+',sum(PropsCoun) as 累计 from Hong_Props group by PropTime'
    --print @str
    exec (@str)/*
    PropTime 道具A 道具B 道具C 道具D 道具E 累计
    2012-02-11 24 15 0 0 0 39
    2012-02-12 0 0 14 2 0 16
    2012-02-13 0 0 0 50 0 50
    2012-02-14 0 9 0 0 0 9
    2012-02-15 20 0 0 0 10 30
    */--动态行列转换,参考这个
      

  2.   

    select 部门,
           sum(case 月份 when '一月份' then 业绩 else 0 end) [一月份],
           sum(case 月份 when '一月份' then 业绩 else 0 end) [二月份],
           sum(case 月份 when '一月份' then 业绩 else 0 end) [三月份]
    from table1
    group by 部门
      

  3.   

    create table table1(月份 varchar(10),部门 varchar(10),业绩 int) 
    insert into table1 values('一月份', '01', 10)
    insert into table1 values('一月份', '02', 10)
    insert into table1 values('一月份', '03', 5)
    insert into table1 values('二月份', '02', 8)
    insert into table1 values('二月份', '04', 9)
    insert into table1 values('三月份', '03', 8)
    go--如果你的月份仅仅是这三个月,则如下:
    select 部门,
           sum(case 月份 when '一月份' then 业绩 else 0 end) [一月份],
           sum(case 月份 when '一月份' then 业绩 else 0 end) [二月份],
           sum(case 月份 when '一月份' then 业绩 else 0 end) [三月份]
    from table1
    group by 部门
    /*
    部门         一月份         二月份         三月份         
    ---------- ----------- ----------- ----------- 
    01         10          10          10
    02         10          10          10
    03         5           5           5
    04         0           0           0(所影响的行数为 4 行)
    */ --如果你的月份不止这三个月,则如下:
    declare @sql varchar(8000)
    set @sql = 'select 部门 '
    select @sql = @sql + ' , sum(case 月份 when ''' + 月份 + ''' then 业绩 else 0 end) [' + 月份 + ']'
    from (select distinct 月份 from table1) as a
    set @sql = @sql + ' from table1 group by 部门'
    exec(@sql) /*
    部门         一月份         二月份         三月份         
    ---------- ----------- ----------- ----------- 
    01         10          10          10
    02         10          10          10
    03         5           5           5
    04         0           0           0(所影响的行数为 4 行)
    */
    drop table table1
    有关次类问题的相关内容参考如下:/*
    标题:普通行列转换(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 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
      

  4.   

    我上面第一段中写错了点.
    更改为如下:
    create table table1(月份 varchar(10),部门 varchar(10),业绩 int) 
    insert into table1 values('一月份', '01', 10)
    insert into table1 values('一月份', '02', 10)
    insert into table1 values('一月份', '03', 5)
    insert into table1 values('二月份', '02', 8)
    insert into table1 values('二月份', '04', 9)
    insert into table1 values('三月份', '03', 8)
    go--如果你的月份仅仅是这三个月,则如下:
    select 部门,
           sum(case 月份 when '一月份' then 业绩 else 0 end) [一月份],
           sum(case 月份 when '二月份' then 业绩 else 0 end) [二月份],
           sum(case 月份 when '三月份' then 业绩 else 0 end) [三月份]
    from table1
    group by 部门
    /*
    部门         一月份         二月份         三月份         
    ---------- ----------- ----------- ----------- 
    01         10          0           0
    02         10          8           0
    03         5           0           8
    04         0           9           0(所影响的行数为 4 行)
    */ --如果你的月份不止这三个月,则如下:
    declare @sql varchar(8000)
    set @sql = 'select 部门 '
    select @sql = @sql + ' , sum(case 月份 when ''' + 月份 + ''' then 业绩 else 0 end) [' + 月份 + ']'
    from (select distinct 月份 from table1) as a
    set @sql = @sql + ' from table1 group by 部门'
    exec(@sql) /*
    部门         一月份         二月份         三月份         
    ---------- ----------- ----------- ----------- 
    01         10          0           0
    02         10          8           0
    03         5           0           8
    04         0           9           0(所影响的行数为 4 行)
    */
    drop table table1
      

  5.   

    /*
    题目:有如下表
    table1
    月份 部门 业绩
    -------------------------------
    一月份 01 10
    一月份 02 10
    一月份 03 5
    二月份 02 8
    二月份 04 9
    三月份 03 8为了得出下面的表,该怎样写查询语句?
    部门 一月份 二月份 三月份
    ---------- ------ ------ ------
    01 10 NULL NULL
    02 10 8 NULL
    03 5 NULL 8
    04 NULL 9 NULL
    */go
    if OBJECT_ID('tbl')is not null
    drop table tbl
    go
    create table tbl(
    月份 varchar(6),
    部门 varchar(2),
    业绩 int
    )
    go
    insert tbl
    select '一月份','01',10 union all
    select '一月份','02',10 union all
    select '一月份','03',5  union all
    select '二月份','02',8  union all
    select '二月份','04',9  union all
    select '三月份','03',8declare @str varchar(2000)
    set @str=''
    select @str=@str+','+'sum(case when 月份='+quotename(月份,'''')+
    ' then 业绩 else 0 end) as '+月份 from tbl group by 月份
    print @str
    set @str='select 部门'+@str+' from tbl group by 部门'
    exec(@str)
    /*
    部门 二月份 三月份 一月份
    01 0 0 10
    02 8 0 10
    03 0 8 5
    04 9 0 0
    */
      

  6.   

    呵呵 好详细 之前简单的答复 已经看懂了 谢谢 下面的再继续学习 吼吼。。 
    PS:我之前一直在琢磨着 有没有可能 只用简单的查询 where and or join 等查出来头都大了。。
    看来太偏激了。谢谢你的回复