Solved

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

Posted on 2014-10-29
8
303 Views
Last Modified: 2014-10-29
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.
0
Comment
Question by:Gadsden Consulting
  • 4
  • 3
8 Comments
 
LVL 73

Expert Comment

by:sdstuber
ID: 40411662
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
 
LVL 73

Expert Comment

by:sdstuber
ID: 40411673
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
 
LVL 73

Accepted Solution

by:
sdstuber earned 425 total points
ID: 40411686
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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 13

Assisted Solution

by:Alexander Eßer [Alex140181]
Alexander Eßer [Alex140181] earned 75 total points
ID: 40411749
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
 

Author Comment

by:Gadsden Consulting
ID: 40411804
Thanks sdstuber and Alexander !
I will review later tonight.
0
 

Author Comment

by:Gadsden Consulting
ID: 40412077
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
 

Author Closing Comment

by:Gadsden Consulting
ID: 40412084
excellent, thanks !
0
 

Author Comment

by:Gadsden Consulting
ID: 40412276
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

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
exp/imp 25 73
SQL View Syntax case etc 5 34
Have a conversion issue with varchar to int in a SQL: Query. 1 30
SQL Use Distinct with two fields 3 10
Cursors in Oracle: A cursor is used to process individual rows returned by database system for a query. In oracle every SQL statement executed by the oracle server has a private area. This area contains information about the SQL statement and the…
From implementing a password expiration date, to datatype conversions and file export options, these are some useful settings I've found in Jasper Server.
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.
This video shows how to Export data from an Oracle database using the Datapump Export Utility.  The corresponding Datapump Import utility is also discussed and demonstrated.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question