Solved

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

Posted on 2014-10-29
8
300 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
 
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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

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

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Introduction A previously published article on Experts Exchange ("Joins in Oracle", http://www.experts-exchange.com/Database/Oracle/A_8249-Joins-in-Oracle.html) makes a statement about "Oracle proprietary" joins and mixes the join syntax with gen…
Have you ever had to make fundamental changes to a table in Oracle, but haven't been able to get any downtime?  I'm talking things like: * Dropping columns * Shrinking allocated space * Removing chained blocks and restoring the PCTFREE * Re-or…
This video shows information on the Oracle Data Dictionary, starting with the Oracle documentation, explaining the different types of Data Dictionary views available by group and permissions as well as giving examples on how to retrieve data from th…
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.

707 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now