本文共 4612 字,大约阅读时间需要 15 分钟。
很多算法、命令都可以通过程序完成,但是要是为了某一个算法,单独去写个clr做支持,意义不大,算法总是千变万化的,所以,我们尝试用数据库本身去完成这些算法
例如有一组数,1、2、5、16.3、22.7、32.6、40、53.1。。。。
求这组数之和小于等100的最大和及其组合
写算法递归排序就好,那么数据库可以实现吗?其实也很简单
首先,我们先定义出这个数字队列成为一个CTE表
with t as ( select convert(float,1) as n union all select 2 union all select 5 union all select 16.3 union all select 22.7 union all select 32.6 union all select 40 union all select 53.1 union all select 14.4 union all select 2.4 union all select 7.2 union all select 64 union all select 32)select * from tn----------------------12516.322.732.64053.114.42.47.26432(13 行受影响)
当然,如果你有正则clr或者split方法,就不用这么定义了
with t as ( select convert(float,match) as n from master.dbo.regexmatches('1,2,5,16.3,22.7,32.6,40,53.1,14.4,2.4,7.2,64,32','[^,]+'))select * from tn----------------------12516.322.732.64053.114.42.47.26432(13 行受影响)
关于正则的clr调用,请参考,,好了,这个不是重点,我们继续看怎么实现求最大和
首先,单个值大于指定和的应该排除掉,然后模拟算数表达式以及结果
declare @val floatset @val=100;with t as ( select convert(float,match) as n from master.dbo.regexmatches('1,2,5,16.3,22.7,32.6,40,53.1,14.4,2.4,7.2,64,32,111.1','[^,]+')),t1 as ( select n as max_val,convert(varchar(max),n) as exp_val,n as sum_val from t where n<=@val)select * from t1max_val exp_val sum_val---------------------- ---------------------------------------------------------------------------------------------------- ----------------------1 1 12 2 25 5 516.3 16.3 16.322.7 22.7 22.732.6 32.6 32.640 40 4053.1 53.1 53.114.4 14.4 14.42.4 2.4 2.47.2 7.2 7.264 64 6432 32 32(13 行受影响)
例如,max_val就是参与计算的最大数字,exp_val就是表达式,sum_val就是表达式的结果
然后我们通过CTE的递归特性来进行最大组合
declare @val floatset @val=100;with t as ( select convert(float,match) as n,sn as id from master.dbo.regexmatches('1,2,5,16.3,22.7,32.6,40,53.1,14.4,2.4,7.2,64,32,111.1','[^,]+')),t1 as ( select id as max_id,convert(varchar(50),n) as exp_val,n as sum_val from t where n<=@val union all select a.id ,convert(varchar(50),b.exp_val+' + ' + convert(varchar,a.n)) ,a.n+b.sum_val from t a,t1 b where a.id>b.max_id and a.n+b.sum_val<=@val)select * from t1order by sum_val descmax_id exp_val sum_val----------- -------------------------------------------------- ----------------------13 5 + 16.3 + 22.7 + 14.4 + 2.4 + 7.2 + 32 10012 1 + 32.6 + 2.4 + 64 10011 2 + 5 + 32.6 + 53.1 + 7.2 99.912 1 + 5 + 22.7 + 7.2 + 64 99.913 1 + 2 + 22.7 + 32.6 + 2.4 + 7.2 + 32 99.913 2 + 16.3 + 40 + 2.4 + 7.2 + 32 99.911 22.7 + 53.1 + 14.4 + 2.4 + 7.2 99.813 2 + 16.3 + 32.6 + 14.4 + 2.4 + 32 99.710 2 + 22.7 + 32.6 + 40 + 2.4 99.713 5 + 53.1 + 2.4 + 7.2 + 32 99.7(1692 行受影响)
这个代码的思路也很简单了,获取数字,并给每个数字进行编号,然后通过递归进行关联,使用的数字的编号大于已有组合的数字id,且和不得大于指定值,然后组合出表达式
当然,由于递归限制,参与运算的数字不能大于100个,另外就是,数字越多效率越低,毕竟这个算是穷举法了
转载地址:http://xxvxi.baihongyu.com/