关于sql实现二维报表的方法

         我们在sql编写中经常会碰到一些二维数表的情况,一个二维数表中每一个数据都有至少两个条件的约束。

         如下图中工人的数据数据,我们规定id以10,20开头的为车间一的工人,30,40开头的为车间二的工人,50,60开头的为车间三的工人,70,80开头的为车间四的工人,90,x1开头的为车间五的工人。Worktime为工作年限。

我们根据上面的数据求如下二维表

如果我们单独查每个框中的人数,是非常简单实现的。只需要加上工作年限在1-3年以及车间一这两个条件就行。完成方式如下:

select count(*) from workers where substr(id,1,2) in ('10','20') and worktime<3;

我们上面报表为5*5的报表,如果我们分别查每个单元的值如果我们按照上述方式一个格一个格的查,我们就要修改25次条件,这样显然是很费力的。而且我们以后很可能面临10*10甚至更多的单元格。

我们可以通过如下几种方式来解决二维数表的问题。

方法一:通过sql以及excl的数据透视表的方式。

我们可以按照车间和年限分组,sql如下:

select

         case

           when substr(id,1,2) in ('10','20') then '车间一'

                   when substr(id,1,2) in ('30','40') then '车间二'

                   when substr(id,1,2) in ('50','60') then '车间三'

                   when substr(id,1,2) in ('70','80') then '车间四'

                   when substr(id,1,2) in ('90','x0') then '车间五'

  end '车间',

  case

          when worktime<3 then '1-3年'

          when worktime>=3 and worktime<5 then '3-5年'

          when worktime>=5 and worktime<7 then '5-7年'

          when worktime>=7 and worktime<9 then '7-9年'

          when worktime>=9 then '9年以上'

 end '年限',

 count(*) '人数'      

 from workers

 group by

        case

           when substr(id,1,2) in ('10','20') then '车间一'

                   when substr(id,1,2) in ('30','40') then '车间二'

                   when substr(id,1,2) in ('50','60') then '车间三'

                   when substr(id,1,2) in ('70','80') then '车间四'

                   when substr(id,1,2) in ('90','x0') then '车间五'

  end,

           case

          when worktime<3 then '1-3年'

          when worktime>=3 and worktime<5 then '3-5年'

          when worktime>=5 and worktime<7 then '5-7年'

          when worktime>=7 and worktime<9 then '7-9年'

          when worktime>=9 then '9年以上'

 end

这样我们就得到了每个单元格相关联的两个条件的所有数据:

然后我们把数据粘贴到excl中,通过数据透视表的方式进行处理:

首先我们选中数据范围,点击插入,选择数据透视表,点击确定。

我们把年限放到x轴,车间放到y轴,人数放入数据中,我们即可得到二维报表。

方法二:通过sql实现

我们的逻辑为把年限通过行列转换的方式,然后通过纵轴的车间进行分组进行加和。

Sql如下:

select     

         case

           when substr(id,1,2) in ('10','20') then '车间一'

                   when substr(id,1,2) in ('30','40') then '车间二'

                   when substr(id,1,2) in ('50','60') then '车间三'

                   when substr(id,1,2) in ('70','80') then '车间四'

                   when substr(id,1,2) in ('90','x0') then '车间五'

  end '车间',

         sum(case when worktime<3 then 1 else 0 end ) '1-3年',

         sum(case when worktime>=3 and worktime<5 then 1 else 0 end ) '3-5年',

         sum(case when worktime>=5 and worktime<7 then 1 else 0 end ) '5-7年',

         sum(case when worktime>=7 and worktime<9 then 1 else 0 end ) '7-9年',

         sum(case when worktime>=9  then 1 else 0 end ) '9年以上'

         from workers

group by

         case

           when substr(id,1,2) in ('10','20') then '车间一'

                   when substr(id,1,2) in ('30','40') then '车间二'

                   when substr(id,1,2) in ('50','60') then '车间三'

                   when substr(id,1,2) in ('70','80') then '车间四'

                   when substr(id,1,2) in ('90','x0') then '车间五'

  end

         ORDER BY

                   case

           when substr(id,1,2) in ('10','20') then '车间一'

                   when substr(id,1,2) in ('30','40') then '车间二'

                   when substr(id,1,2) in ('50','60') then '车间三'

                   when substr(id,1,2) in ('70','80') then '车间四'

                   when substr(id,1,2) in ('90','x0') then '车间五'

  end

        

运行结果如下:

 

建立运行环境-Excel Vba,可移植到VB环境中(需修改一些代码) '仿制简单的SQL查询语句,用于对二维数组的查询 '参照SQL语句:Select * From array [Where conditions] [Distinct fields] [ResultWithTitle] ' '实现功能: ' 依条件设置查询数组,返回包含查询字段(或全部字段)的数组,可多条件组合。 ' 条件运算符包括:> = < >= <= <> , like(正则表达式) ' '附注: ' 使用此函数,需要在文件中引用正则表达式脚本 Microsoft VBScript Regular Expressions x.x ' (根据不同的电脑配置和环境此处会有差异) '算法简要: ' 1、查询条件运算符:仅有 >, =, <, >=, <=, <> , like(正则表达式) ' 本函数中仅有上述运算符。原因在于,更多的运算符编制逻辑过于复杂,又不太常用。 ' 为了尽可能多地容纳各种运算关系,添加了正则表达式匹配运算, ' 在某个单一条件中,正则几乎可以容纳绝大部分的比对运算关系了。 ' 2、数字比较: ' 采用了将数字型字符串类型转换为数字之后再比较的方法,结果更为准确。 ' 3、其他算法和运算速度: ' 编制过程中,试验过使用 正则+逻辑分支+表达式引用 的方法, ' 可以实现几乎等同于SQL查询语句的复杂功能,而且代码更简捷。 ' 但运算速度相差过于悬殊(大概几十到上百倍 - "一闪而过"和"一袋烟"的差距!),最后不得不放弃。 ' 所以现在的版本相当于一个简化了的select语句,但对于大多数查询情况而言够用了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值