当前位置: 代码迷 >> SQL >> 固定分组计算的sql简单化
  详细解决方案

固定分组计算的sql简单化

热度:39   发布时间:2016-05-05 09:59:33.0
固定分组计算的sql简化

   在数据库应用开发中,我们经常需要面对复杂的SQL式计算,固定分组就是其中一种。固定分组的分组依据不在待分组的数据中,而是来自于外部,比如另一张表、外部参数、条件列表。对于特定类型的固定分组,用SQL实现还算简单,比如:分组依据来自另一张表,且对分组次序没有要求,但要实现其他情况就困难了。

   集算器可以轻松解决固定分组中的各类难题,下面用几个例子来说明。

   表sales存储着订单记录,其中CLIENT列是客户名,AMOUNT列是订单金额,请将sales按照“潜力客户列表”进行分组,并对各组的AMOUNT列汇总求和。表sales的部分数据如下:


   案例一:潜力客户列表来自于另外一张表potential的Std字段,只有四条记录,依次为:TAS、DSGC、GC、ZTOZ,并且客户ZTOZ不在sales表中。本案例要求按照上述记录顺序来分组汇总。

   假如我们对分组的顺序没有要求,那么SQL可以较简单地实现本案例,代码形如:

select potential.std as client, sum(sales.amount) as amount from potential left join client on potential.std=sales.client group by potential.std

   但本案例要求按照特定的顺序来分组,要实现这种算法,用SQL就必须制造一个用于排序的字段,最后还要用子查询去掉这个字段。而用集算器实现本案例会简单很多,代码如下:

   A1、B1:从数据库检索数据,分别命名为sales和potential,如下所示:


   A3[email protected](potential:Std,Client)

   这句代码使用了函数align,它将sales的Client字段按照potentail的Std字段分为四个组,如下:

   可以看到,前三个组是sales中已有的数据,而第四个组不在sales中,因此是空值。另外,[email protected],如果不用这个函数选项,则只取每组的第一条。

   A4=pjoin(potential.(Std),A3.(~.sum(Amount)))

   这句代码用函数pjoin将两部分数据进行横向合并,一部分是potential.(Std),这表示potential的Std字段;另一部分是A3.(~.sum(Amount)),这表示对A3中每组数据的Amount字段求和。本案例的最终结果如下:

   案例二:潜力客户列表是固定值,但客户的数量较多。

   如果客户的数量较少,用SQL时可以用union语句将所有的客户拼成一个假表,如果客户数量较多,这么做就可不取了,必须新建一张表持久保存数据才行。用集算器实现本案例可以省去建表的麻烦,代码如下:

   上述代码中,A2是个逗号分隔的字符串,可以轻松表达大量的固定值。

   案例三:潜力客户列表是外部参数,形如:TAS,BON,CHO,ZTOZ

   外部参数经常变化,在SQL中用union来制造假表就很不方便了,只能创建一个临时表,将参数解析后一条条插入临时表,再进行后续的计算,但用集算器来做则不必建立临时表。

   首先定义一个参数arg1,如下:

   修改脚本文件,如下:


   运行脚本,并输入的参数值,假设参数值为”TAS,BON,CHO,ZTOZ”,如下:


   由于分组依据和案例一相同,因此最终的计算结果也一样。

   注意,A2中的代码可以将字符串”TAS,BON,CHO,ZTOZ“转变成序列["TAS","DSGC","GC","ZTOZ"]。如果输入参数直接就是["TAS","DSGC","GC","ZTOZ"],则可以省略这个转换的步骤。

   案例四:固定分组的分组依据可以是数值,也可以是条件,比如:将订单金额按照1000、2000、4000划分为四个区间,每个区间一组订单,统计各组订单的总额。

   如果条件是已知,那就可以将这些条件写死在SQL里,如果条件是动态的外部参数,则需要用JAVA等高级语言拼凑SQL,过程非常复杂。而集算器支持动态表达式,可以轻松实现本案例,代码如下:

   上述代码中,变量byFac是本案例的分组依据,包含四个字符串条件。byFac也可以是外部参数,或者来自于数据库中的视图或表。A4中的最终结果如下:


   案例五:
   上述条件分组中,条件恰好没有发生重叠,但实际上发生重叠的情况很常见,比如将订单金额按照如下规则分组:

   1000至4000:常规订单r14

   2000以下:非重点订单r2

   3000以上:重点订单r3

   这时,r2和r3都会和r14发生条件重叠。条件发生重叠时,我们有时希望数据不重叠,即先取出符合r14的数据,再从剩下的数据中筛选出r2,以此类推。

   集算器的函数enum支持数据重叠的条件分组,如下:

   A3中的分组结果如下:


   计算结果如下:


   有时我们希望分组结果中包含重叠数据,即先从sales中取出符合r14的数据,再从完整的sales中取出符合r2的数据,以此类推。此时,[email protected],即将A3中的代码改为:[email protected](byFac,Amount),此时分组结果如下:


   图中红框里的数据是重复的。最后的计算结果如下:


   另外,集算器可被报表工具或java程序调用,调用的方法也和普通数据库相似,使用它提供的JDBC接口即可向java主程序返回ResultSet形式的计算结果,具体方法可参考相关文档。

版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案