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

  • 相关阅读:
    day02操作系统/编程语言分类/python解释器介绍/python解释器多版本共存
    网络编程-互联网协议(网络编程)/基于TCP协议的套接字通信/加上通信循环/加上连接循环
    每天新的英语单词
    re模块(正则表达式)
    包的使用/time与datetime模块/random模块/打印进度条/shutil模块
    模块的使用之import/模块的使用之 from import/区分python文件的两种用途
    列表生成式与生成器表达式模块的使用模块的使用之from.......import区分python文件的两种用途文件的搜索路径
    三元表达式/函数的递归/匿名函数及其应用/map函数/reduce函数/ filter函数
    函数的嵌套/名称空间/作用域/函数对象/闭包函数
    跟未名学Office
  • 原文地址:https://www.cnblogs.com/xchit/p/1856451.html
Copyright © 2011-2022 走看看