Re: how do i split a string
From: Bob Jones <email_at_me.not>
Date: Sat, 18 Oct 2008 10:27:34 -0500
Message-ID: <TdnKk.2814$Ei5.1451@flpi143.ffdc.sbc.com>
>>>>> Mark D Powell schrieb:
>>>>> Mark, it can be hardly called enhancement, because this construct
>>>>> wasn't documented even in 11g, but you are correct, behaviour was
>>>>> changed (somewhere around 9i) - on 8.1.7.4 it gives ORA-01436: CONNECT
>>>>> BY loop in user data, but works quite well in Oracle 9.2.0.8 ( except
>>>>> the circumstance, that 9i sqlplus didn't return more than 1 row from
>>>>> dual, what can be easily faked by wrapping it into subquery). But that
>>>>> is not essential for Michel's solution, it will work with any row
>>>>> generator (like select rownum from all_tables) - i guess, he chose it
>>>>> just because it is compact. More important for his solution is
>>>>> availability of analytical functins, but they were introduced in 8.1.6
>>>>> iirc.
>>>>> Best regards
>>>>> Maxim
Date: Sat, 18 Oct 2008 10:27:34 -0500
Message-ID: <TdnKk.2814$Ei5.1451@flpi143.ffdc.sbc.com>
"Maxim Demenko" <mdemenko_at_gmail.com> wrote in message news:48F9F293.1080501_at_gmail.com...
> Bob Jones schrieb: >> "Maxim Demenko" <mdemenko_at_gmail.com> wrote in message >> news:48F99429.8070204_at_gmail.com... >>> Bob Jones schrieb: >>>> "Maxim Demenko" <mdemenko_at_gmail.com> wrote in message >>>> news:48F8EBB5.2030208_at_gmail.com...
>>>>> Mark D Powell schrieb:
>>>>>> On Oct 15, 11:07 am, "Michel Cadot" <micadot{at}altern{dot}org> >>>>>> wrote: >>>>>>> "Mark D Powell" <Mark.Pow..._at_eds.com> a écrit dans le message de >>>>>>> news: >>>>>>> 5c6a55cc-f094-4937-bc47-00e92d8cf..._at_u27g2000pro.googlegroups.com... >>>>>>> On Oct 13, 9:43 pm, "Bob Jones" <em..._at_me.not> wrote: >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>>> <emdproduct..._at_hotmail.com> wrote in message >>>>>>>> news:8a7a71fc-e783-4e0a-8a00-ae8d984c8024_at_d31g2000hsg.googlegroups.com... >>>>>>>>> group, >>>>>>>>> I have a record like this >>>>>>>>> 12**5*** >>>>>>>>> I need to know the 1st occurance of *, and length of it >>>>>>>>> the 2nd occurance of * and the length of it >>>>>>>>> for example, for 12**5***, I need to get 3263 >>>>>>>>> meaning the 1st one start at 3, length is 2, the 2nd one start at >>>>>>>>> 6, >>>>>>>>> the length is 2 >>>>>>>>> Your help is highly appreciated >>>>>>>> select regexp_instr('12**5***','\*+',1,1) >>>>>>>> ||length(regexp_substr('12**5***','\*+',1,1)) >>>>>>>> ||regexp_instr('12**5***','\*+',1,2) >>>>>>>> ||length(regexp_substr('12**5***','\*+',1,2)) >>>>>>>> from dual >>>>>>> Emdproduct, Bob's answers requires that you have Oracle version >>>>>>> 10g+. >>>>>>> If you have an earlier version of Oracle a different solution will >>>>>>> have to be sought. >>>>>>> >>>>>>> HTH -- Mark D Powell -- >>>>>>> >>>>>>> --------------------------------------------- >>>>>>> >>>>>>> SQL> def in='12**5***' >>>>>>> SQL> with >>>>>>> 2 enumerating as ( >>>>>>> 3 select substr('&in',level,1) elem, level rn, >>>>>>> 4 case >>>>>>> 5 when level = 1 >>>>>>> 6 or >>>>>>> decode(substr('&in',level-1,1),'*','*','#') >>>>>>> 7 != >>>>>>> decode(substr('&in',level,1),'*','*','#') >>>>>>> 8 then row_number() over (order by level) >>>>>>> 9 end flag >>>>>>> 10 from dual >>>>>>> 11 connect by level <= length('&in') >>>>>>> 12 ), >>>>>>> 13 grouping as ( >>>>>>> 14 select elem, >>>>>>> 15 max(flag) over (order by rn) grp >>>>>>> 16 from enumerating >>>>>>> 17 ) >>>>>>> 18 select grp start_point, count(*) nb_stars >>>>>>> 19 from grouping >>>>>>> 20 where elem = '*' >>>>>>> 21 group by grp >>>>>>> 22 order by grp >>>>>>> 23 / >>>>>>> START_POINT NB_STARS >>>>>>> ----------- ---------- >>>>>>> 3 2 >>>>>>> 6 3 >>>>>>> >>>>>>> 2 rows selected. >>>>>>> >>>>>>> Regards >>>>>>> Michel- Hide quoted text - >>>>>>> >>>>>>> - Show quoted text - >>>>>> Michel, isn't connect by level against dual a 10g enhancement? >>>>>> >>>>>> -- Mark D Powell --
>>>>> Mark, it can be hardly called enhancement, because this construct
>>>>> wasn't documented even in 11g, but you are correct, behaviour was
>>>>> changed (somewhere around 9i) - on 8.1.7.4 it gives ORA-01436: CONNECT
>>>>> BY loop in user data, but works quite well in Oracle 9.2.0.8 ( except
>>>>> the circumstance, that 9i sqlplus didn't return more than 1 row from
>>>>> dual, what can be easily faked by wrapping it into subquery). But that
>>>>> is not essential for Michel's solution, it will work with any row
>>>>> generator (like select rownum from all_tables) - i guess, he chose it
>>>>> just because it is compact. More important for his solution is
>>>>> availability of analytical functins, but they were introduced in 8.1.6
>>>>> iirc.
>>>>>
>>>>> Best regards
>>>>>
>>>>> Maxim
>>>> In 9i or 8i, you can do something like this. >>>> >>>> select instr(string,'*') Pos1, >>>> nvl(length(substr(string,instr(string,'*'))),0) - >>>> nvl(length(ltrim(substr(string,instr(string,'*')),'*')),0) Len1, >>>> >>>> instr(string,'*',instr(string,'*')+nvl(length(substr(string,instr(string,'*'))),0) >>>> - nvl(length(ltrim(substr(string,instr(string,'*')),'*')),0)+1) Pos2, >>>> nvl(length(substr(ltrim(substr(string,instr(string,'*')),'*'), >>>> instr(ltrim(substr(string,instr(string,'*')),'*'),'*'))),0) - >>>> >>>> nvl(length(ltrim(substr(ltrim(substr(string,instr(string,'*')),'*'), >>>> instr(ltrim(substr(string,instr(string,'*')),'*'),'*')),'*')),0) Len2 >>>> from dual >>>> >>>> >>>> >>> This would give the right answer, provided you are looking exactly for >>> the first and second occurency ( the same is valid for your regexp >>> query). >>> The sql statements by Michel are suitable for more generic case, when >>> you don't know, how many occurencies of searched sting there are. >>> Another alternative which should as well work for earlier versions ( >>> except with clause of course) >>> >>> SQL> with t as ( >>> 2 select '12**5***899******55**' s from dual >>> 3 ) >>> 4 -- End test data >>> 5 select min(pos) pos,count(*) len from ( >>> 6 select t.s, >>> 7 r.r, >>> 8 instr(t.s, '*', 1, r) pos, >>> 9 instr(t.s, '*', 1, r) - r shift >>> 10 from t, (select rownum r from all_tables) r >>> 11 where instr(t.s, '*', 1, r) > 0 >>> 12 ) >>> 13 group by shift >>> 14 order by pos >>> 15 ; >>> >>> POS LEN >>> ---------- ---------- >>> 3 2 >>> 6 3 >>> 12 6 >>> 20 2 >>> >>> >>> Best regards >>> >>> Maxim >> >> First and second occurrences were precisely what the OP was asking for. >> Also the result needs to be in one line. > > I never assured your replies were wrong or not what OP asked for. > Just some thoughts on possible alternative approaches. >
Ok, I just wasn't sure why you were providing an alternative solution to a different problem. Received on Sat Oct 18 2008 - 10:27:34 CDT