sql两个字段的值求和_SPL 简化 SQL 案例详解:多级关联

在数据库应用开发中,我们经常需要面对复杂的SQL式计算,多级关联就是其中一种。SQL的join语句比较抽象,只适合表达简单的关联关系,一旦关联的层级较多,相应的代码就会变得非常复杂。而SPL则可以利用对象引用来表达关联关系,从而使代码更加直观,下面就用一个例子来加以说明。

表channel存储着某网站所有的频道及其上级频道的对应关系,分别用ID和PARENT字段来表示,最多四级,其中root代表网站本身(即根节点)。表中部分数据如下:

92918f3d5078c3e25bfe174093d4cabe.png

现在想要根据参数输入的ID,分层列出该频道所有下级的名称,同一层的下级之间用逗号分隔。假设参数arg1的值是p1,我们期望的结果如下图所示:

a4b8c03f71d3cc5a8cbecd907ee45ae0.png

SPL代码如下:

34e47e70e4380150faa14c167a5d60a4.png

A1:查询表channel,部分结果如下图所示:

18569ecd5d5b08c85b870c4a50611437.png

B1:>A1.switch(PARENT,A1:ID),使用函数switch将表中PARENT字段替换成对应的记录引用,如下图所示:

2da4848b017e983047dcdea2d1e70f7b.png

切换后,可以直接用PARENT.ID来表示上级(父)频道,而PARENT. PARENT. PARENT.ID则可以直接表示上三级(曾祖父)频道。虽然在SQL中也可以用join来表示这种自连接,但层级多了后显然容易产生混乱。

A2:=create(ID,LEVEL,SUB),建立一个空序表,用来存储最终的计算结果。

A3:=A1.select(PARENT.ID==arg1),从表中查询出上级(父)频道等于参数arg1的记录,即:arg1的下一级(子)频道。计算结果如下:

4a3484d1628f962e541f97b188a259e7.png

B3:>A2.insert(0,arg1,1,A3.(NAME).string()),在A2中追加一条记录,第一个字段值是arg1;第二个字段值为1,表示第一级子频道;第三个字段为表达式A3.(NAME).string(),表示取出A3中的列NAME,拼成逗号分隔的字符串。计算结果如下:

b967d41857c645aed91318e1f7a63958.png

A4:=A1.select(PARENT.PARENT.ID==arg1),这句代码和A3类似,表示从表中查询出arg1的下两级(孙子)频道。结果如下:

f556ab6f33b834b4e0f765435c513a66.png

A5和A4类似,表示取出arg1的下三级(曾孙)频道。用类似的办法可以轻松取出下N级的频道。

B4、B5和B3类似,都是向A2中追加新记录,只是level字段改为2和3。执行完B5后,A2就是本次运算的最终结果:

19b15da88cececba68a42d0064e0e1bf.png

刚才参数arg1的值为p1,如果输入c12,则计算结果如下:

8057891187aa89d0f74ba8cc3cfb6ae7.png

有时我们希望看到更清晰的数据,比如将某个频道的所有下级频道一条条列出,并标出层级关系。如下图所示:

ac86592e393da738419685acc0b81325.png

要想实现这种算法,可以使用下面的代码:

7bba1275357b931f97b85d6d6456f8eb.png

红色字体为变动后的代码,其中B3中的代码是=A2.insert(0,arg1,1,A3),这表示直接将A3的记录存储在A2中,假设参数arg1的值为p1,则计算结果如下:

62ea976211709f2e7ff425ae995b977e.png

点开SUB字段,可以看到详细的记录:

4d9a804f5af8ed992510ad421bc232f7.png

可以看到,SPL的字段值是泛型的,可以存储记录组,或者单条记录。而函数switch的本质就是将外键切换为主表中对应的记录。

执行完B5后,A2中的结果如下:

e3ec2a0dafb3f5aa22d0433954b44a07.png

A6:=A2.(~.SUB.new(A2.ID,A2.LEVEL,ID:SUBID,NAME)),用来将A2中ID和LEVEL拼到SUB字段里的每条记录中。其中A2.()表示对A2进行计算,计算中可以使用“~”来表示A2中的每条记录,~.SUB则表示每条记录的SUB字段(记录组)。函数new用来生成新的序表,即:A2中的ID字段、LEVEL字段,SUB中的ID字段、NAME字段。计算完成后,A6的值如下:

513863a3fe4748d9fda1518cdc058689.png

A7=A6.union(),这句代码用来将A7的各组记录拼在一起,形成最终计算结果:

3eebeb17adca1a9a4be6673a799a69ae.png

有时我们需要直接列出每个频道的所有下级频道。要想实现这种算法,可以使用SPL的for语句,代码如下:

6e61544e999df8a3ea4d0016eff15550.png

A3中的代码for A1.(ID)表示循环A1的ID字段,每次取出一条,可以用循环语句所在的单元格A3来表示循环变量。循环的作用范围可以用缩进来表示,例子中的循环范围就是B 3:C5。最终的计算结果在A7中,部分数据如下:

e4ff4b6e4a24b6be059fb22e9506d25b.png

从这些例子可以看出,使用SPL简化多级关联问题时,思路直观明了,代码简洁易懂,层级关系清晰可见。与SQL相比,这样的SPL代码可以大幅度降低开发成本,并极大地简化后期优化和维护工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值