zoukankan      html  css  js  c++  java
  • 交叉表

    --交叉表查询
    create table tb_nm(
    fwtime datetime,
    keywords  varchar(10),
    num int,
    yiyuan varchar(10)

    )
    insert into tb_nm  values('2009-1-1','keywords1',1,'2')
    insert into tb_nm  values('2009-1-1','keywords2',1,'30')
    insert into tb_nm  values('2009-1-1','keywords3',1,'2')
    insert into tb_nm  values('2009-1-1','keywords4',1,'30')
    insert into tb_nm  values('2009-1-1','keywords5',1,'2')
    insert into tb_nm  values('2009-1-1','keywords6',1,'31')
    insert into tb_nm  values('2009-1-1','keywords7',1,'2')
    insert into tb_nm  values('2009-1-1','keywords8',1,'2')

    select * from tb_nm


    DECLARE @keywords varchar(10)
    DECLARE @sql varchar(1000)

    set @sql='select convert(varchar(10),fwtime,120) fwtime, '

    DECLARE C12 CURSOR FOR

    select keywords 
    from tb_nm where yiyuan='2'


    OPEN C12

    FETCH NEXT FROM C12 INTO
           @keywords

    IF @@FETCH_STATUS <> 0
    BEGIN
         DEALLOCATE C12
         RAISERROR('没有符合条件的数据',16,-1)
         RETURN
    END
    WHILE(@@FETCH_STATUS = 0)
    BEGIN
         SET @sql=@sql+' sum(case keywords when '+char(39)+@keywords+char(39)+' then num else 0 end) as '+ @keywords+','

         FETCH NEXT FROM C12 INTO
            @keywords
    END
    DEALLOCATE C12

    set @sql=substring(@sql,1,len(@sql)-1)
    set @sql=@sql+' from tb_nm where  yiyuan='+char(39)+'2'+char(39)+' group by fwtime'

    exec(@sql)

    //////////////////////////////////////////////////////////////////////
    create table a
    (
     year  nvarchar(20),
     month nvarchar(20),
     value nvarchar(20)
    )

    insert into a(year,month,value) values('2009','1','11');
    insert into a(year,month,value) values('2009','2','12');
    insert into a(year,month,value) values('2009','3','13');
    insert into a(year,month,value) values('2009','4','14');
    insert into a(year,month,value) values('2010','1','21');
    insert into a(year,month,value) values('2010','2','22');
    insert into a(year,month,value) values('2010','3','23');
    insert into a(year,month,value) values('2010','4','24');
    insert into a(year,month,value) values('2010','4','24');


    select * From a pivot(max(value) for month in ([1],[2],[3],[4])) pvt

    ////////////////////////////////////////////////////////////////////////

    createtable tb (姓名 varchar(20),部门 varchar(20),职务 varchar(20))
    insertinto tb
    select'姓名1', '部门1','职务1'
    unionall
    select'姓名2','部门2','职务2'
    unionall
    select'姓名3','部门3','职务2'
    unionall
    select'姓名4','部门4','职务3'
    unionall
    select'姓名5','部门4','职务4'

    --sql 2000静态SQL,指职务固定为职务1,2,3,4
    select 部门,
     
    sum(case 职务 when'职务1'then1else0end) '职务1',
     
    sum(case 职务 when'职务2'then1else0end) '职务2',
     
    sum(case 职务 when'职务3'then1else0end) '职务3',
     
    sum(case 职务 when'职务4'then1else0end) '职务4'
    from tb
    groupby 部门
    /*
    部门                   职务1         职务2         职务3         职务4        
    -------------------- ----------- ----------- ----------- -----------
    部门1                  1           0           0           0
    部门2                  0           1           0           0
    部门3                  0           1           0           0
    部门4                  0           0           1           1

    (所影响的行数为 4 行)
    */

    --sql 2000动态SQL语句,指职务名称不固定。
    declare@sqlvarchar(8000)
    set@sql='select 部门 '
    select@sql=@sql+' , sum(case 职务 when '''+ 职务 +''' then 1 else 0 end) ['+ 职务 +']'
    from (selectdistinct 职务 from tb) as a
    set@sql=@sql+' from tb group by 部门'
    exec(@sql)
    /*
    部门                   职务1         职务2         职务3         职务4        
    -------------------- ----------- ----------- ----------- -----------
    部门1                  1           0           0           0
    部门2                  0           1           0           0
    部门3                  0           1           0           0
    部门4                  0           0           1           1
    */

    droptable tb
    /////////////////////////////////////////////////////////////////////////////

    /*
    标题:普通行列转换(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
    -------------------
    */

    createtable tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
    insertinto tb values('张三' , '语文' , 74)
    insertinto tb values('张三' , '数学' , 83)
    insertinto tb values('张三' , '物理' , 93)
    insertinto tb values('李四' , '语文' , 74)
    insertinto tb values('李四' , '数学' , 84)
    insertinto tb values('李四' , '物理' , 94)
    go

    --SQL SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)
    select 姓名 as 姓名 ,
     
    max(case 课程 when'语文'then 分数 else0end) 语文,
     
    max(case 课程 when'数学'then 分数 else0end) 数学,
     
    max(case 课程 when'物理'then 分数 else0end) 物理
    from tb
    groupby 姓名

    --SQL SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
    declare@sqlvarchar(8000)
    set@sql='select 姓名 '
    select@sql=@sql+' , max(case 课程 when '''+ 课程 +''' then 分数 else 0 end) ['+ 课程 +']'
    from (selectdistinct 课程 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@sqlvarchar(8000)
    select@sql=isnull(@sql+'],[' , '') + 课程 from tb groupby 课程
    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 分数 else0end) 语文,
     
    max(case 课程 when'数学'then 分数 else0end) 数学,
     
    max(case 课程 when'物理'then 分数 else0end) 物理,
     
    cast(avg(分数*1.0) asdecimal(18,2)) 平均分,
     
    sum(分数) 总分
    from tb
    groupby 姓名

    --SQL SERVER 2000 动态SQL。
    declare@sqlvarchar(8000)
    set@sql='select 姓名 '
    select@sql=@sql+' , max(case 课程 when '''+ 课程 +''' then 分数 else 0 end) ['+ 课程 +']'
    from (selectdistinct 课程 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) asdecimal(18,2)) 平均分 , sum(分数) 总分 from tb groupby 姓名) n
    where m.姓名 = n.姓名

    --SQL SERVER 2005 动态SQL。
    declare@sqlvarchar(8000)
    select@sql=isnull(@sql+',' , '') + 课程 from tb groupby 课程
    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.姓名
    ')

    droptable tb   

    ------------------
    --
    ----------------

    /*
    问题:如果上述两表互相换一下:即表结构和数据为:
    姓名 语文 数学 物理
    张三 74  83  93
    李四 74  84  94
    想变成(得到如下结果):
    姓名 课程 分数
    ---- ---- ----
    李四 语文 74
    李四 数学 84
    李四 物理 94
    张三 语文 74
    张三 数学 83
    张三 物理 93
    --------------
    */

    createtable tb(姓名 varchar(10) , 语文 int , 数学 int , 物理 int)
    insertinto tb values('张三',74,83,93)
    insertinto tb values('李四',74,84,94)
    go

    --SQL SERVER 2000 静态SQL。
    select*from
    (
    select 姓名 , 课程 ='语文' , 分数 = 语文 from tb
    unionall
    select 姓名 , 课程 ='数学' , 分数 = 数学 from tb
    unionall
    select 姓名 , 课程 ='物理' , 分数 = 物理 from tb
    ) t
    orderby 姓名 , case 课程 when'语文'then1when'数学'then2when'物理'then3end

    --SQL SERVER 2000 动态SQL。
    --
    调用系统表动态生态。
    declare@sqlvarchar(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,不包含列名为姓名的其它列
    orderby 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
    unionall
    select 姓名 as 姓名 , 课程 ='数学' , 分数 = 数学 from tb
    unionall
    select 姓名 as 姓名 , 课程 ='物理' , 分数 = 物理 from tb
    unionall
    select 姓名 as 姓名 , 课程 ='平均分' , 分数 =cast((语文 + 数学 + 物理)*1.0/3asdecimal(18,2)) from tb
    unionall
    select 姓名 as 姓名 , 课程 ='总分' , 分数 = 语文 + 数学 + 物理 from tb
    ) t
    orderby 姓名 , case 课程 when'语文'then1when'数学'then2when'物理'then3when'平均分'then4when'总分'then5end

    droptable tb

  • 相关阅读:
    Spring基础知识
    Hibernate基础知识
    Struts2基础知识
    在eclipse里头用checkstyle检查项目出现 File contains tab characters (this is the first instance)原因
    java后台获取cookie里面值得方法
    ckplayer 中的style.swf 中的 style.xml 中的修改方法
    java hql case when 的用法
    Windows下Mongodb安装及配置
    Mongodb中经常出现的错误(汇总)child process failed, exited with error number
    Mac 安装mongodb
  • 原文地址:https://www.cnblogs.com/xchit/p/1856451.html
Copyright © 2011-2022 走看看