当前位置: 首页 > news >正文

如何用 esProc 补充数据库 SQL 的缺失能力

某些数据库 SQL 缺失必要的能力,通常要编写大段的代码,才能间接实现类似的功能,有些情况甚至要改用存储过程,连结构都变了。常见的比如:生成时间序列、保持分组子集、动态行列转换、自然序号、相对位置、按序列和集合生成多条记录、累积计算、条件分组、跨库计算、集合计算、序列计算、自关联结构、递归计算、对齐式关联等。用下面几个例子快速感受一下。

生成时间序列:某库表的 Time 字段是时间,时间的间隔有时大于 1 分钟。

TimeValue
10:10:053
10:11:064
10:13:135
10:13:199
10:13:328
10:14:352

现在要将数据每分钟分成一个窗口,补上缺失的窗口,对每个窗口统计 4 个值:前一个窗口的最后一条 start_value;本窗口的最后一条;本窗口的最小值;本窗口的最大值。第一分钟的 start_value 用本窗口的第一条记录;如果缺少某窗口的数据,则用前一个窗口的最后一条代替。

startendstart_valueend_valueminmax
10:10:0010:11:003333
10:11:0010:12:003444
10:12:0010:13:004444
10:13:0010:14:004859
10:14:0010:15:008222

很多数据库的 SQL 没有方便的方法生成月份序列,很多数据库要用多层嵌套查询 + 多个窗口函数才能间接实现。

保持分组子集:某表存储多个账号在多个日期发生的事件。

RowAccount NumberDate
110012011-01-10
210012011-02-01
310012011-02-20
410012011-02-22
520012011-04-11
620012012-01-01
720012012-01-30
820012012-02-09

现在要找出每个账号下符合条件的一对事件,分别是:日期最早的事件 a、距 a 事件 30 天以上的事件中日期最早的事件 b。

RowAccount NumberDate
110012011-01-10
310012011-02-20
520012011-04-11
620012012-01-01

SQL 分组后必须立刻汇总,很难按条件 b 筛选记录,只能用 join 语句配合多个 CTE 子句间接实现。

动态行列转换:某库表记录了不同产品每个月的销售额,其中产品的值未知。

productmonthamount
AA1100
AA1150
AA2200
AA2120
BB2180
BB2220
CC380

现在要对产品、月份分组,对销售额求和,再将产品由行转列。

monthAABBCC
1250
2320400
380

某些数据库的 SQL 缺失动态行列转换能力,行转列时必须写出列名,很多数据库只能改用存储过程。

esProc SPL 内置丰富的计算类库,可以补充这些数据库 SQL 缺失的能力,比如上面 3 个例子:

"https://c.raqsoft.com.cn/article/1742353802112"


“@从 SQL 到 SPL:计算组内符合条件的一对最小值 - 乾学院”

“从 SQL 到 SPL:Create columns from distinct values of a column - 乾学院”

下面,我们就来尝试一下如何将 esProc 集成到应用中。

先下载 esProc,推荐标准版:集算器 产品下载 | 报表加速器下载-半结构化计算软件下载

下载并安装相应的版本。

安完后,试一下 esProc IDE 是否可以正常访问数据库。先把数据库的 JDBC Driver 放到目录 "[安装目录]\common\jdbc",这是 esProc 的类路径之一。比如 mySQL 的 JDBC:

Picture1png


打开 esProc IDE,找到菜单 "Tool->Connect to Data Source",新建 JDBC 数据源,填入具体数据库的连接信息。下面是一个 mySQL 的数据源:

Picture2png


返回到数据源界面,试着连接数据源,跨库运算时可以同时连接多个数据源。如果数据源名变成粉色,说明配置成功。

Picture3png


在 IDE 中新建脚本,写 SPL 语句,连接 mysql 数据库,加载第 1 个例子的数据:

=connect("mysql").query@x("select * from main")

按 ctrl-F9 执行,可以在 IDE 右边看到执行结果,以数据表的形式呈现,这对调试 SPL 代码很方便。

Picture4png

加载数据正常后,就可以写正式的 SPL 代码了,第 1 个例子:

 A
1=connect("mysql").query@x("select * from main where time>? and time<=?",arg1,arg2)
2=A1.run(Time=time@m(Time))
3=list=periods@s(A2.min(Time),A2.max(Time),60)
4=A2.align@a(list,Time)
5=A4.new(list(#):start, elapse@s(start,60):end, sv=ifn(end_value[-1],~.Value):start_value, ifn(~.m(-1).Value, sv):end_value, ifn(~.min(Value),sv):min, ifn(~.max(Value),sv):max)

先用参数过滤;再将时间改为整分钟数;生成连续分钟的时间序列;将数据按时间序列对齐,每组数据对应一分钟的窗口;按要求用每组数据生成一条新记录。

把上面脚本保存在某个目录中,比如 D:\data\procMain.splx,运行后可以看到结果:

Picture5png

第 2 个例子:

 A
1=connect("mysql").query@x("select * from ventas")
2=A1.group(#2)
3=A2.conj(~1 | ~.select@1((#3 - A2.~1.#3)>30))

加载数据;按 2 个字段分组,但不汇总;取每组第 1 条,再筛选出距第 1 条 30 天以上的记录,也取第 1 条;合并这 2 条记录,最后合并各组的处理结果。

保存成 D:\data\proc2.splx,执行后看结果:

Picture6png


第 3 个例子:

=connect("mysql").query@x("select * from ventas").pivot@s(month;product,sum(amount))

加载数据后动态转置,执行结果:

Picture7png


在 IDE 中调试无误后,就可以把 esProc 集成到 Java 环境中了。
从目录 "[安装目录]\esProc\lib" 下找到 esProc JDBC 相关的 jar 包:esproc-bin-xxxx.jar、icu4j_60.3.jar。

Picture8png


将这两个 jar 包部署到 Java 开发环境的类路径下。
再从目录 "[安装目录]\esProc\config" 下找到 esProc 配置文件 raqsoftConfig.xml,同样部署到 Java 开发环境的类路径下。

Picture9png


配置文件中要改的配置项是 mainPath,这表示脚本等文件的默认路径。注意数据源的信息也在配置文件中。
接下来,就可以编写 Java 代码,通过 esProc JDBC 调用 SPL 脚本了,例子 1:

Class.forName("com.esproc.jdbc.InternalDriver");
Connection con= DriverManager.getConnection("jdbc:esproc:local://");
PreparedStatement st = con.prepareCall("call procMain(?,?)");
st.setTime(1,Time.valueOf("10:00:00"));
st.setTime(2,Time.valueOf("11:00:00"));
ResultSet rs = st.executeQuery();

可以看到,调用 SPL 脚本的过程和调用存储过程是一样的。计算后结果如下:

Picture10png


脚本文件不是必须的,可以把 SPL 脚本转为 SPL 代码,像 SQL 那样嵌入 Java。先在 IDE 中打开例子 2 的脚本文件,选中有代码的单元格 A1-A3,再点击菜单 "Edit->Copy->Code copy",这样就把多行多列的网格代码转成了单行的 SPL 代码,暂存在粘贴板里。

Picture11png


将转换后的 SPL 代码复制到 Java 代码中

Connection con= DriverManager.getConnection("jdbc:esproc:local://");
PreparedStatement st = con.prepareStatement("==connect(\"mysql\").query@x(\"select * from ventas\")\n=A1.group(#2) \n=A2.conj(~1 | ~.select@1((#3 - A2.~1.#3)>30))");
ResultSet rs = st.executeQuery();
可以看到,Java调用SPL代码的过程和调用SQL代码一样。运行后可以看到结果:

可以看到,Java调用SPL代码的过程和调用SQL代码一样。运行后可以看到结果:

Picture12png


有些 SPL 代码比较简单,没必要用 esProc IDE 编写调试,那就可以直接写在 Java 里。比如例子 3,直接在 Java 中嵌入 SPL 代码:

Connection con= DriverManager.getConnection("jdbc:esproc:local://");
PreparedStatement st = con.prepareStatement("=connect(\"mysql\").query@x(\"select * from ventas\").pivot@s(month;product,sum(amount))");
ResultSet rs = st.executeQuery();

执行结果像下面这样:

Picture13png


乾学院上还有很多补充 SQL 缺失能力的例子,开发遇到问题时可以去找找解决办法。

相关文章:

  • 湖南(源点咨询)市场调研 商业综合体定位调研分享(中篇)
  • mapstruct使用详解
  • 12.第二阶段x64游戏实战-远程调试
  • 美团一面总结
  • list的一些常用接口
  • 流量统计实例
  • 域AD渗透手法【密码喷洒技术】
  • 【JavaScript】二十三、M端事件 + 轮播图Swiper插件
  • USB(TYPE-C)转串口(TTL)模块设计讲解
  • C++之 动态数组
  • 河南普瑞维升企业案例:日事清SOP流程与目标模块实现客户自主简报功能落地
  • 智能语音处理+1.5使用PocketSphinxshinx实现语音转文本(100%教会)
  • Pinpoint - 大型分布式系统的 APM(应用性能管理)工具
  • 强化学习的数学原理(五) MonteCarlo learning
  • MoogDB数据库日常维护技巧与常见问题解析
  • 未能安装包“Microsoft.VisualStudio.XXXXX
  • 3D语义地图中的全局路径规划!iPPD:基于3D语义地图的指令引导路径规划视觉语言导航
  • BR_输出功率(RF/TRM/CA/BV-01-C [Output Power])
  • 从零开始实现 MobileViT 注意力机制——轻量级Transformer Vision Model 的新思路
  • PyTorch框架学习01
  • 天津红桥网站建设/网站seo技术能不能赚钱
  • 建设 政务数据共享网站/软件外包公司是什么意思
  • 网站开发网站设计的标准/2021年关键词排名
  • 做网站开发的想接私活/网站功能
  • 网站 动画 怎么做的/网络推广公司经营范围
  • 基于jsp的社团组织网站建设/搜索引擎优化工作