SQL实现排列组合功能
昨天朋友发给我一个sql编程题目:
大概意思就是随机选择几个人使得总分最接近某个值,这不正是数学中学习过的排列组合中的组合吗?
排列组合中A(15,3)表示排列,从15个中有序抽取3个,所以一共有15*14*13种排列结果,123、132、213、231、312、321表示6种不同的结果
排列组合中C(15,3)表示组合,从15个中无序选择3个,所以一共有(15*14*13)/(3*2*1)种组合结果,123、132、213、231、312、321表示同一种结果
大概思路:如果使用编程语言,比如java、c编写时,可以使用嵌套循环或者递归实现,通过控制循环进行遍历,将三个人的成绩累加后保存在数组中;但是如果使用sql实现循环或者递归的话,对于大部分人(包括我)来说是比较难理解的,也是比较难实现的,所以我们只能使用 join 来实现。
但是怎样关联是需要我们思考的,left join?right join?还是inner join?关联条件又是什么?
1.我们看一下表中的数据,姓名列是有序排列的
如果我们进行C(15,2)操作时,可以进行如下关联:
select * from
tmp_lhj a1 --tmp_lhj为以上excel数据在库中临时表的表名
left join
tmp_lhj a2 on a可以进行1.name<a2.name
where a2.name is not null
如果我们进行A(15,2)操作时,可以进行如下关联:
select * from
tmp_lhj a1 --tmp_lhj为以上excel数据在库中临时表的表名
left join
tmp_lhj a2 on a1.name != a2.name
where a2.name is not null
排列和组合的区别在于是否有序:
【1】如果进行组合,则顺序12和顺序21是重复的,应该去掉一条,所以关联条件使用<正好可以将21这一条去掉;(顺序12指的是第一次选择A01,第二次选择A02)
【2】如果进行排列,顺序12和顺序21是两种结果,使用!=关联可以将两条结果均保留。
【3】如果第一个人选择A15,则后面不能选择比它排序更高的人了,所以第二个人为空,这样的话这一条数据就没有意义,因此加一个限制条件a2.name is not null
2.上面是选取两个人,依次类推,当我们取3个人
进行C(15,3)操作时,可以进行如下关联:
select * from
tmp_lhj a1 --tmp_lhj为以上excel数据在库中临时表的表名
left join
tmp_lhj a2 on a1.name<a2.name
left join
tmp_lhj a3 on a2.name<a3.name
where a3.name is not null
进行A(15,3)操作时,可以进行如下关联:
select * from
tmp_lhj a1 --tmp_lhj为以上excel数据在库中临时表的表名
left join
tmp_lhj a2 on a1.name!=a2.name
left join
tmp_lhj a3 on a2.name!=a3.name
where a3