Extract value between two characters with varying positions - sql

NOTE: I am using TSQL
I need to be able to extract data from the middle of a string. Both the length of the data I need, and the length of the string will vary.
Here are examples of the complete string:
362 Any Rd - NewPc#:420010079274892700465647513335 - StopID:12345
362 Any Rd - NewPc#:4200644392748927004720180006426006 - StopID:12345
362 Any Rd - NewPc#:00006675214112593057 - StopID:12345
362 Random Rd - NewPc#:420063709274892700465647550149 - StopID:4567
I only need the following from the above strings:
420010079274892700465647513335
4200644392748927004720180006426006
00006675214112593057
420063709274892700465647550149
Can someone please help me figure this out?

You can use a combination of substring and charindex.
Fiddle
select
substring(somecolumn, charindex(':',somecolumn) + 1,
len(somecolumn) -
charindex('-', reverse(somecolumn)) - 1 - charindex(':',somecolumn))
from tablename

Select SUBSTRING( Note,CHARINDEX ('#:' , Note, 1 ) +2,
CHARINDEX ( ' - S' ,Note ,1 )-
CHARINDEX ('#:' , Note, 1 ) -2 )
from OER
You use 2 functions for your table oer:
1st is to find the location for ":"
CHARINDEX ('#:' , Note, 1 ) +2
The +2 is to get rid of the "#:"
You need to use this 2 times, once again for the " - S" To see how many characters you want to go.
CHARINDEX ( ' - S' ,Note ,1 )
And the 2nd function is Substring to use part of your Note
link sql fiddle:
http://sqlfiddle.com/#!3/95ce8/7/0

An example is this: You have a string and the character $
String :
aaaaa$bbbbb$ccccc
Code:
SELECT SUBSTRING('aaaaa$bbbbb$ccccc',CHARINDEX('$','aaaaa$bbbbb$ccccc')+1, CHARINDEX('$','aaaaa$bbbbb$ccccc',CHARINDEX('$','aaaaa$bbbbb$ccccc')+1) -CHARINDEX('$','aaaaa$bbbbb$ccccc')-1) as My_String
Output:
bbbbb

Related

Extracting certain text between two characters

I have a nvarchar string from which I need to extract certain text from between characters.
Example: 1.abc.5,m001-1-Exit,822-FName-18001233321--2021-09-23 13:53:10 Thursday-m001-1-Exit-Swipe,Card NO: 822User ID: FNameName: 18001233321Dept: Read Date: 2021-09-23 13:53:10 ThursdayAddr: m001-1-ExitStatus: Swipe,07580ec2000002a52E917D0000000000372BA56E11010000
What I need:
| Name | Phone Number |
| -------- | -------------- |
| FName | 1800123321 |
My Attempt:
SELECT SUBSTRING(col, LEN(LEFT(col, CHARINDEX ('-', col))) + 1, LEN(col) - LEN(LEFT(col, CHARINDEX ('-', col))) - LEN(RIGHT(col, LEN(col) - CHARINDEX ('-', col))) - 1);
One way:
Use patindex to find "FName-"
Remove the start of the string up until and including "FName-"
Use patindex to find "--"
Remove the rest of the string from and including "--"
You can consolidate the query down to one line, but you'll find yourself repeating parts of the logic - which I like to avoid. And calculating one thing at a time makes it easier to debug.
select
A.Col
, B.StringStart
, C.NewString
, patindex('%--%',C.NewString) NewStringEnd
, substring(C.NewString,1,patindex('%--%',C.NewString)-1) -- <- Required Result
from (
values
(N'1.abc.5,m001-1-Exit,822-FName-18001233321--2021-09-23 13:53:10 Thursday-m001-1-Exit-Swipe,Card NO: 822User ID: FNameName: 18001233321Dept: Read Date: 2021-09-23 13:53:10 ThursdayAddr: m001-1-ExitStatus: Swipe,07580ec2000002a52E917D0000000000372BA56E11010000')
) A (Col)
cross apply (
values
(patindex('%FName-%',Col))
) B (StringStart)
cross apply (
values
(substring(A.Col,B.StringStart+6,len(A.Col)-B.StringStart-6))
) C (NewString);

How to extract the number from a string using Oracle?

I have a string as follows: first, last (123456) the expected result should be 123456. Could someone help me in which direction should I proceed using Oracle?
It will depend on the actual pattern you care about (I assume "first" and "last" aren't literal hard-coded strings), but you will probably want to use regexp_substr.
For example, this matches anything between two brackets (which will work for your example), but you might need more sophisticated criteria if your actual examples have multiple brackets or something.
SELECT regexp_substr(COLUMN_NAME, '\(([^\)]*)\)', 1, 1, 'i', 1)
FROM TABLE_NAME
Your question is ambiguous and needs clarification. Based on your comment it appears you want to select the six digits after the left bracket. You can use the Oracle instr function to find the position of a character in a string, and then feed that into the substr to select your text.
select substr(mycol, instr(mycol, '(') + 1, 6) from mytable
Or if there are a varying number of digits between the brackets:
select substr(mycol, instr(mycol, '(') + 1, instr(mycol, ')') - instr(mycol, '(') - 1) from mytable
Find the last ( and get the sub-string after without the trailing ) and convert that to a number:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE test ( str ) AS
SELECT 'first, last (123456)' FROM DUAL UNION ALL
SELECT 'john, doe (jr) (987654321)' FROM DUAL;
Query 1:
SELECT TO_NUMBER(
TRIM(
TRAILING ')' FROM
SUBSTR(
str,
INSTR( str, '(', -1 ) + 1
)
)
) AS value
FROM test
Results:
| VALUE |
|-----------|
| 123456 |
| 987654321 |

Retrieving right two words in char DB2 field

Using SQL, how can I retrieve the 2 words from the right end of a CHAR(30) field?
namefield = "My name is Bill Smith"
results = Bill Smith
This is untested, but maybe something like:
SELECT REVERSE(SUBSTRING(REVERSE(namefield) , 0, CHARINDEX(' ', REVERSE(namefield), CHARINDEX(' ', REVERSE(namefield), 0)+1))) FROM TABLE
Replace table with your table. Let me know if it works!
If you use LOCATE_IN_STRING you can say -X to search backwards - as op. to charindex which only only look forward.
select
-- locate_in_string(str,' ',-1),
-- substr(str,1,locate_in_string(str,' ',-1)-1),
-- length(str) - locate_in_string(str,' ',-1),
-- locate_in_string(str,' ',-7),
-- locate_in_string(str,' ',(-1* (length(str) - locate_in_string(str,' ',-1))) -2 ),
-- substr(str,1,11) || '<-',
-- substr(str,1,locate_in_string(str,' ',(-1* (length(str) - locate_in_string(str,' ',-1))) -2 )-1),
substr(str,locate_in_string(str,' ',(-1* (length(str) - locate_in_string(str,' ',-1))) -2 ))
FROM (
VALUES('My name is Bill Smith')
) AS T(str)
Here I start at the point of the last space and search for the prior space and then pass that to substr.
https://www.ibm.com/support/knowledgecenter/en/SSEPGG_9.7.0/com.ibm.db2.luw.sql.ref.doc/doc/r0054098.html
I've included my testing code above -- you can see how I test various parts by removing the comment for that line. This technique my prove useful in your testing.

How to Extract the middle characters from a string without an specific index to start and end it before the space character is read?

I have a column that contains data like:
AB-123 XYZ
ABCD-456 AAA
BCD-789 BBB
ZZZ-963
Y-85
and this is what i need from those string:
123
456
789
963
85
I need the characters from the left after the dash('-') character, then ends before the space character is read.
Thank You guys.
Note: Original tag on this question was Oracle and this answer is based on that tag. Now that, tag is updated to SqlServer, this answer is no longer valid, if somebody looking for Oracle solution, this may help.
Use regular expression to arrive at sub string.
select trim(substr(regexp_substr('ABCD-456 AAA','-[0-9]+ '),2)) from dual
'-[0-9]+ ' will grab any string pattern which starts with dash has one or more digits and ends with a ' ' and returns number with dash
substr will remove '-' from above output
trim will remove any trailing ' '
Check This.
Using Substring and PatIndex.
select
SUBSTRING(colnm, PATINDEX('%[0-9]%',colnm),
PATINDEX('%[^0-9]%',ltrim(RIGHT(colnm,LEN(colnm)-CHARINDEX('-',colnm)))))
from
(
select 'AB-123 XYZ' colnm union
select 'ABCD-456 AAA' union
select 'BCD-789 BBB' union
select 'ZX- 23 BBB'
)a
OutPut :
Try this
http://rextester.com/YTBPQD69134
CREATE TABLE Table1 ([col] varchar(12));
INSERT INTO Table1
([col])
VALUES
('AB-123 XYZ'),
('ABCD-456 AAA'),
('BCD-789 BBB');
select substring
(col,
charindex('-',col,1)+1,
charindex(' ',col,1)-charindex('-',col,1)
) from table1;
Assume all values has '-' and followed by a space ' '. Below solution will not tolerant to exception case:
SELECT
*,
SUBSTRING(Value, StartingIndex, Length) AS Result
FROM
-- You can replace this section of code with your table name
(VALUES
('AB-123 XYZ'),
('ABCD-456 AAA'),
('BCD-789 BBB')
) t(Value)
-- Use APPLY instead of sub-query is for debugging,
-- you can view the actual parameters in the select
CROSS APPLY
(
SELECT
-- Get the first index of character '-'
CHARINDEX('-', Value) + 1 AS StartingIndex,
-- Get the first index of character ' ', then calculate the length
CHARINDEX(' ', Value) - CHARINDEX('-', Value) - 1 AS Length
) b

Parse column value based on delimeters

Here is a sample of my data:
ABC*12345ABC
BCD*234()
CDE*3456789(&(&
DEF*4567A*B*C
Using SQL Server 2008 or SSIS, I need to parse this data and return the following result:
12345
234
3456789
4567
As you can see, the asterisk (*) is my first delimiter. The second "delimiter" (I use this term loosely) is when the sequence of numbers STOP.
So, basically, just grab the sequence of numbers after the asterisk...
How can I accomplish this?
EDIT:
I made a mistake in my original post. An example of another possible value would be:
XWZ*A12345%$%
In this case, I would like to return the following:
A12345
The value can START with an alpha character, but it will always END with a number. So, grab everything after the asterisk, but stop at the last number in the sequence.
Any help with this will be greatly appreciated!
You could do this with a little patindex and charindex trickery, like:
; with YourTable(col1) as
(
select 'ABC*12345ABC'
union all select 'BCD*234()'
union all select 'CDE*3456789(&(&'
union all select 'DEF*4567A*B*C'
union all select 'XWZ*A12345%$%'
)
select left(AfterStar, len(Leader) + PATINDEX('%[^0-9]%', AfterLeader) - 1)
from (
select RIGHT(AfterStar, len(AfterStar) - PATINDEX('%[0-9]%', AfterStar) + 1)
as AfterLeader
, LEFT(AfterStar, PATINDEX('%[0-9]%', AfterStar) - 1) as Leader
, AfterStar
from (
select RIGHT(col1, len(col1) - CHARINDEX('*', col1)) as AfterStar
from YourTable
) as Sub1
) as Sub2
This prints:
12345
234
3456789
4567
A12345
If you ignore that this is in SQL then the first thing that comes to mind is Regex:
^.*\*(.*[0-9])[^0-9]*$
The capture group there should get what you want. I don't know if SQL has a regex function.