最近同事让我帮忙写一个根据参数进行一个全排列,大概意思就是给几个字符串,算出字符串一共有多少种组合方式。
根据给出的字符abc,算出所有的组合方式,如下。
a,ab,abc,ac,acb,b,ba,bac,bc,bca,c,ca,cab,cb,cba
或者找出两位或三位组合
ab,ac,ba,bc,ca,cb
创建模拟环境
drop table gsc_test;
create table gsc_test(parentstr varchar2(10),str varchar2(2),childstr varchar2(10));
insert into gsc_test values('','a','b');
insert into gsc_test values('a','b','c');
insert into gsc_test values('b','c','');
commit;
实例
select replace (sys_connect_by_path(str,'/'),'/') "group"
from gsc_test t
connect by nocycle prior str != t.str
输出
group
a
ab
abc
ac
acb
b
ba
bac
bc
bca
c
ca
cab
cb
cba
语法解析
select sys_connect_by_path(column1,'分隔符') from [start with] ... [nocycle] prior column1 = column2
sys_connect_by_path,是将递归的路劲根据指定的分隔符拼接起来。start with 是从哪里开始递归,上面的例子如果从字母a开始递归,就不会递归字母b和c。level是递归自动生成的列,显示的是往下递归了几层。replace是替换函数,自行学习哈。
select sys_connect_by_path(str,'/') "group",t.str,level
from gsc_test t /*where level = 2*/ --这里的条件会在递归完成之后再对结果进行筛选
start with str = 'a' /*where level = 2*/ --可以在这里加上level等级条件,获取想要的组合长度
connect by nocycle prior str != t.str
输出
group STR LEVEL
/a a 1
/a/b b 2
/a/b/c c 3
/a/c c 2
/a/c/b b 3
connect by后面接参数和递归的条件。nocycle用于检测到死循环停止递归,正常结束。根据递归的条件可能会出现a–>b–c递归不重复的情况,这时候递归会正常结束。还有可能会出现a–>b–>c–>a无限递归的情况,这时候如果不添加nocycle参数Oracle会报错。prior 参数可放在column1前面或者column2前面,如果放在columb2前面相当于表达式where column2 = column1的值。
prior 在column1前面
select replace (sys_connect_by_path(str,'/'),'/') "group",t.str,level
from gsc_test t
start with str = 'a'
connect by nocycle prior str = t.parentstr;
输出
group STR LEVEL
a a 1
ab b 2
abc c 3
prior 在column2前面
select replace (sys_connect_by_path(str,'/'),'/') "group",t.str,level
from gsc_test t
start with str = 'c'
connect by nocycle str = prior t.parentstr;
输出
group STR LEVEL
c c 1
cb b 2
cba a 3