need workaround to REGEXP_COUNT Oracle, due to not having 11g

I need a workraound to REGEXP_COUNT, due to not having 11g (we are moving there, but not anytime soon).

I need to know how many times of a pattern. The pattern is straightforward, e.g., M5T34W123R5F567S12, which is
M(Mon) followed by [0-9]+, or T(Tues)+[0-9]+ etc. through S(Sat)+[0-9]+.

I have the basics worked out, and I could work with this in a brute force manner, but thought I'd see if there are any tricks I might be able to use since REGEXP_COUNT isn't available.

WITH tab2 AS 
(SELECT 'M5T34R56' a FROM dual UNION
 SELECT 'M5T34W123R5F567S12' FROM dual UNION
 SELECT 'M56T456W56F56' FROM dual UNION
 SELECT 'T10R9' FROM dual
) 
SELECT DISTINCT a, Regexp_instr(a,'(^[MWTRFS]+[0-9]+$)') AS Matches,
                Regexp_substr(a,'([MWTRFS]+[0-9]+)',1,1) AS "1st",
                Regexp_substr(a,'([MWTRFS]+[0-9]+)',1,2) AS "2nd" ,
                Regexp_substr(a,'([MWTRFS]+[0-9]+)',1,3) AS "3rd",
                Regexp_substr(a,'([MWTRFS]+[0-9]+)',1,4) AS "4th",
                Regexp_substr(a,'([MWTRFS]+[0-9]+)',1,5) AS "5th" ,
                Regexp_substr(a,'([MWTRFS]+[0-9]+)',1,6) AS "6th"                 
                -- Regexp_count(a,'([MWTRFS]+[0-9]+)',1,'i') AS Num_occurances   
FROM tab2                

A	               MATCHES	1st	2nd	3rd	4th	5th	6th
M56T456W56F56	              0	M56	T456	W56	F56		
M5T34R56	              0	M5	T34	R56			
M5T34W123R5F567S12	0	M5	T34	W123	R5	F567	S12
T10R9	                      0	T10	R9				
		

Open in new window


My plan is to count the number of non-null results and use that.
Gadsden ConsultingIT SpecialistAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sdstuberCommented:
WITH tab2 AS
(SELECT 'M5T34R56' a FROM dual UNION
 SELECT 'M5T34W123R5F567S12' FROM dual UNION
 SELECT 'M56T456W56F56' FROM dual UNION
 SELECT 'T10R9' FROM dual
)
select x.*,
   nvl2("1st",1,0) +
   nvl2("2nd",1,0) +
   nvl2("3rd",1,0) +
   nvl2("4th",1,0) +
   nvl2("5th",1,0) +
   nvl2("6th",1,0)  Num_occurances
from
(SELECT DISTINCT a, Regexp_instr(a,'^[MWTRFS]+[0-9]+$') AS Matches,
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,1) AS "1st",
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,2) AS "2nd",
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,3) AS "3rd",
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,4) AS "4th",
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,5) AS "5th",
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,6) AS "6th"                  
FROM tab2) x
0
sdstuberCommented:
note - I took out the extra parentheses from your expressions.

Extra () are not free.  Where the SQL parser will simply ignore extraneous parentheses, the regular expression parser will not.

They create sub-expressions which means an extra level of parsing which isn't needed for yours.  Thus making the execution more expensive.

If you need them use them, if you don't then don't.
0
sdstuberCommented:
Another version - this will determine how many day/hour pairs there are even if there are more than 6.

WITH tab2 AS 
(SELECT 'M5T34R56' a FROM dual UNION
 SELECT 'M5T34W123R5F567S12' FROM dual UNION
 SELECT 'M56T456W56F56' FROM dual UNION
 SELECT 'T10R9' FROM dual UNION ALL
SELECT 'M1M2M3M4M5M6M7M8M9M10' from dual
) 
SELECT DISTINCT a, Regexp_instr(a,'^[MWTRFS]+[0-9]+$') AS Matches,
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,1) AS "1st",
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,2) AS "2nd",
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,3) AS "3rd",
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,4) AS "4th",
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,5) AS "5th",
                Regexp_substr(a,'[MWTRFS]+[0-9]+',1,6) AS "6th",
                (select max(level) from dual connect by Regexp_substr(a,'[MWTRFS]+[0-9]+',1,level) is not null)Num_occurances                                              
FROM tab2

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

Alexander Eßer [Alex140181]Software DeveloperCommented:
Another possible approach could be adapting the workaround shown in this link:

http://oracleappstech-vinoth.blogspot.de/2012/03/regexpinstr-function-for-oracle-9i.html
0
Gadsden ConsultingIT SpecialistAuthor Commented:
Thanks sdstuber and Alexander !
I will review later tonight.
0
Gadsden ConsultingIT SpecialistAuthor Commented:
sdstuber,

I was able to check at home, and looks great !

good tip on not using extraneous paren's . . .

your second version looks good too, here's what I'll use as my workaround, and then loop through the num occurrences and process the parts.
returns 6 - M5T34W123R5F567S12
SELECT '&mtg_time', Regexp_instr('&mtg_time','^[MWTRFS]+[0-9]+$') AS Matches,
                Regexp_substr('&mtg_time','[MWTRFS]+[0-9]+',1,1) AS "1st",
                Regexp_substr('&mtg_time','[MWTRFS]+[0-9]+',1,2) AS "2nd",
                Regexp_substr('&mtg_time','[MWTRFS]+[0-9]+',1,3) AS "3rd",
                Regexp_substr('&mtg_time','[MWTRFS]+[0-9]+',1,4) AS "4th",
                Regexp_substr('&mtg_time','[MWTRFS]+[0-9]+',1,5) AS "5th",
                Regexp_substr('&mtg_time','[MWTRFS]+[0-9]+',1,6) AS "6th",
                (select max(level) from dual connect by Regexp_substr('&mtg_time','[MWTRFS]+[0-9]+',1,level) is not null) as Num_occurances                                              
FROM dual

Open in new window


Alexander, that's a good link and slick workaround, thx.
0
Gadsden ConsultingIT SpecialistAuthor Commented:
excellent, thanks !
0
Gadsden ConsultingIT SpecialistAuthor Commented:
Oh, I realize my solution is simpler, i.e.
SELECT '&mtg_time' as mtg_time, (select max(level) from dual connect by Regexp_substr('&mtg_time','[MWTRFS]+[0-9]+',1,level) is not null) as Num_occurances                                              
FROM dual

I don't quite get the level / connect by, but we did that recently so I'll ponder that tomorrow . . . an elegant workaround to not having regexp_count.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Oracle Database

From novice to tech pro — start learning today.