|
加了两个hints,终于可以不用中间表了:
每次划掉三位以内的:
WITH
n AS (
SELECT TO_NUMBER(REPLACE(SYS_CONNECT_BY_PATH(rn,','),',','')) num
FROM (SELECT ROWNUM-1 rn FROM DUAL CONNECT BY ROWNUM<=10)
START WITH rn>0
CONNECT BY NOCYCLE rn<>PRIOR rn AND LEVEL<=3
)
,nums AS (
SELECT /*+ materialize */ TO_CHAR(num) num, TO_CHAR(numnum) numnum,LENGTH(numnum) l2
FROM (SELECT num, num*num numnum FROM n)
WHERE LENGTH(numnum)=11-LENGTH(TRANSLATE('$0123456789','$'||numnum,'$'))
)
,p AS (
SELECT /*+ materialize */ pos,l
FROM (SELECT ROWNUM pos FROM DUAL CONNECT BY ROWNUM<=10),(SELECT ROWNUM l FROM DUAL CONNECT BY ROWNUM<=3)
WHERE pos+l<=11
)
,t (str,len,path) AS (
SELECT REPLACE(SYS_CONNECT_BY_PATH(n,','),',') ,LEVEL,''
FROM (SELECT ROWNUM-1 n FROM DUAL CONNECT BY ROWNUM<=10)
START WITH n>0
CONNECT BY NOCYCLE LEVEL<=3
UNION ALL
SELECT REPLACE(str,num,numnum)
,t.len+nums.l2-p.l
,path||SUBSTR(str,1,p.pos-1)||'('||num||')'||SUBSTR(str,p.pos+p.l)||','
FROM nums,t,p
WHERE p.pos+p.l-1<=t.len
and substr(SUBSTR(str,pos,l),-1)<>'0' and SUBSTR(str,p.pos,p.l)>'1'
AND LENGTH(TRANSLATE('$1234567890','$'||REPLACE(str,num,numnum),'$'))
= 11 - (t.len+nums.l2-p.l)
AND SUBSTR(str,p.pos,p.l) = nums.num
)
CYCLE str SET cycle_flag TO 'Y' DEFAULT 'N'
SELECT path||str FROM (
SELECT * FROM t ORDER BY len DESC,str DESC
)
WHERE ROWNUM<=1;
PATH||STR
----------------------------------------------------------------------------------------------
38(7),38(49),(3)82401,98(24)01,98(5)7601,98(2)57601,98457(6)01,984(5)73601,9842573601
Elapsed: 00:00:11.85
每次划掉五位以内的:
WITH
n AS (
SELECT TO_NUMBER(REPLACE(SYS_CONNECT_BY_PATH(rn,','),',','')) num
FROM (SELECT ROWNUM-1 rn FROM DUAL CONNECT BY ROWNUM<=10)
START WITH rn>0
CONNECT BY NOCYCLE rn<>PRIOR rn AND LEVEL<=5
)
,nums AS (
SELECT /*+ materialize */ TO_CHAR(num) num, TO_CHAR(numnum) numnum,LENGTH(numnum) l2
FROM (SELECT num, num*num numnum FROM n)
WHERE LENGTH(numnum)=11-LENGTH(TRANSLATE('$0123456789','$'||numnum,'$'))
)
,p AS (
SELECT /*+ materialize */ pos,l
FROM (SELECT ROWNUM pos FROM DUAL CONNECT BY ROWNUM<=10),(SELECT ROWNUM l FROM DUAL CONNECT BY ROWNUM<=5)
WHERE pos+l<=11
)
,t (str,len,path) AS (
SELECT REPLACE(SYS_CONNECT_BY_PATH(n,','),',') ,LEVEL,''
FROM (SELECT ROWNUM-1 n FROM DUAL CONNECT BY ROWNUM<=10)
START WITH n>0
CONNECT BY NOCYCLE LEVEL<=3
UNION ALL
SELECT REPLACE(str,num,numnum)
,t.len+nums.l2-p.l
,path||SUBSTR(str,1,p.pos-1)||'('||num||')'||SUBSTR(str,p.pos+p.l)||','
FROM nums,t,p
WHERE p.pos+p.l-1<=t.len
and substr(SUBSTR(str,pos,l),-1)<>'0' and SUBSTR(str,p.pos,p.l)>'1'
AND LENGTH(TRANSLATE('$1234567890','$'||REPLACE(str,num,numnum),'$'))
= 11 - (t.len+nums.l2-p.l)
AND SUBSTR(str,p.pos,p.l) = nums.num
)
CYCLE str SET cycle_flag TO 'Y' DEFAULT 'N'
SELECT path||str FROM (
SELECT * FROM t ORDER BY len DESC,str DESC
)
WHERE ROWNUM<=1;
PATH||STR
------------------------------------------------------------------------------
19(8),(1964),3857(2)96,3857(49)6,(3)85724016,98572401(6),9857240136
Elapsed: 00:00:13.94 |
|