最近看到一个这样的面试题:
实现一个函数(使用Java), 输入一个数组, 例如 1121121123115 ; 找到所有符合A+B=C模式的连续的值; 例如 1+1=2; 112+3 = 115 ;
要求最终结果如下:
1+1=2
1+1=2
1+1=2
1+2=3
12+11=23
112+3=115
撇开Java和PL/SQL不看,毕竟也就是一个三重或者四重循环的事情,笔者手痒,希望能从SQL端入手,解决这个问题。
注1:下文中测试用字符串为:112112112113224225123
笔者的SQL如下:
思想是:借用字符串的长度,生成一个1~length(str)的结果集,然后利用这个结果集进行自连接,暴力破解出所有的组合可能性,满足where条件,也就是A+B=C这种情况的,
我们筛选出来,这就是最终的结果。where条件中的t1.rn+t2.rn+t3.rn+t4.rn是为了屏蔽substr函数中,截取长度不够的问题。
从分析和运行结果来看,功能是ok的,但是性能上似乎有点问题。当然,用SQL去解一些本应该程序做的事情,性能大多数时候都不会好到哪去。但是,在有限范围内,总会有人去无限优化,去接近极限值。下面就是newkid大叔的写法,他避免了第三次截取,只要结果集保证前两次截取剩下的字符串,正好可以满足前两次连续截取的字符串值的和的
后缀%匹配,如第一次截取1,第二次截取2,剩下值是3**********就满足了条件。
----newkid进阶写法
注2:在DM管理工具中执行时,请修改配置文件COMPATIBLE_MODE=2
经过测试,后面的写法,性能提升10~15倍。
结论:建索引、看计划、考虑扫描方式是优化的常规方法,但是并非适用于所有场合,偶尔换个思路,跳出局限,或许效果会更好。