SQL syntax alphanumeric characters, SQL Server - sql

If I pull this ID down from my source system it looks like 9006ABCD.
What would the syntax look like if I just want to return 9006 as the ID?
Essentially, I don't need the alpha characters.

Assuming that '9006ABCD' is a string value, then you can extract the leading numbers using:
select left(id, patindex('%[^0-9]%', id + 'X') - 1)
Of course, there may be easier ways. If you just want the first four characters, then use left(id, 4).

Related

Get Rightmost Pair of Letters from String in SQL

Given a field with combinations of letters and numbers, is there a way to get the last (Rightmost) pair of letters (2 letters) in SQL?
SAMPLE DATA
RT34-92837DF82982
DRE3-9292928373DO
FOR THOSE, I would want
DF and
DO
For clarity, there will only be numbers after these letters.
Edits
This is for SQL Server.
I would remove any characters that aren't letters, using REGEXP_REPLACE or similar function based on your DBMS.
regexp_replace(col1, '[^a-zA-Z]+', '')
Then use a RIGHT or SUBSTRING function to select the "right-most".
right(regexp_replace(col1, '[^a-zA-Z]+', ''), 2)
substring(regexp_replace(col1, '[^a-zA-Z]+', ''),len(regexp_replace(col1, '[^a-zA-Z]+', ''))-2,len(regexp_replace(col1, '[^a-zA-Z]+', ''))
If you can have single occurrences of letters ('DF1234A124') then could change the regex pattern to remove those also - ([^a-zA-Z][a-zA-Z][^a-zA-Z])|[^a-zA-Z]
As you said, there will only be numbers after these letters, you can use the Trim and Right functions as the following:
select
Right(Trim('0123456789' from val), 2) as res
from t
Note: This is valid from SQL Server 2017.
For older versions try the following:
select
Left
(
Right(val, PATINDEX('%[A-Z]%', Reverse(val))+1),
2
) as res
from t
See demo

Sort a VARCHAR column in SQL Server that contains numbers?

I have a column in which data has letters with numbers.
For example:
1 name
2 names ....
100 names
When sorting this data, it is not sorted correctly, how can I fix this? I made a request but it doesn’t sort correctly.
select name_subagent
from Subagent
order by
case IsNumeric(name_subagent)
when 1 then Replicate('0', 100 - Len(name_subagent)) + name_subagent
else name_subagent
end
This should work
select name_subagent
from Subagent
order by CAST(LEFT(name_subagent, PATINDEX('%[^0-9]%', name_subagent + 'a') - 1) as int)
This expression will find the first occurrence of a letter withing a string and assume anything prior to this position is a number.
You will need to adapt this statement to your needs as apparently your data is not in Latin characters.
With a bit of tweaking you should be able to achieve exactly what you're looking for:
select
name_subagent
from
Subagent
order by
CAST(SUBSTRING(name_subagent,0,PATINDEX('%[A-Z]%',name_subagent)) as numeric)
Note, the '%[A-Z]%' expression. This will only look for the first occurrence of a letter within the string.
I'm not considering special characters such as '!', '#' and so on. This is the bit you might want to play around with and adapt to your needs.

SQL / REGEX pattern matching

I want to use regex through sql to query some data to return values. The only valid values below returned would be "GB" and "LDN", or could also be "GB-LDN"
G-GB-LDN-TT-TEST
G-GB-LDNN-TT-TEST
G-GBS-LDN-TT-TEST
As it writes the first GB set needs to have 2 characters specifically, and the LDN needs to have 3 characters specifically. Both sets/groups seperated by an - symbol. I kind of need to extract the data but at the same time ensure it is within that pattern. I took a look at regex but I can't see how to, well it's like substring but I can't see it.
IF i undertsand correctly, you could still use of substring() function to extract the string parts separated by -.
select left(parsename(a.string, 3), 2) +'-'+ left(parsename(a.string, 2) ,3) from
(
select replace(substring(data, 1, len(data)-charindex('-', reverse(data))), '-', '.') [string] from <table>
) a
As in above you could also define the length of extracted string.
Result :
GB-LDN
GB-LDN
GB-LDN

Extracting specific part of column values in Oracle SQL

I want to extract a specific part of column values.
The target column and its values look like
TEMP_COL
---------------
DESCOL 10MG
TEGRAL 200MG 50S
COLOSPAS 135MG 30S
The resultant column should look like
RESULT_COL
---------------
10MG
200MG
135MG
This can be done using a regular expression:
SELECT regexp_substr(TEMP_COL, '[0-9]+MG')
FROM the_table;
Note that this is case sensitive and it always returns the first match.
I would probably approach this using REGEXP_SUBSTR() rather than base functions, because the structure of the prescription text varies from record to record.
SELECT TRIM(REGEXP_SUBSTR(TEMP_COL, '(\s)(\S*)', 1, 1))
FROM yourTable
The pattern (\s)(\S*) will match a single space followed by any number of non-space characters. This should match the second term in all cases. We use TRIM() to remove a leading space which is matched and returned.
how do you know what is the part you want to extract? how do you know where it begins and where it ends? using the white-spaces?
if so, you can use substr for cutting the data and instr for finding the white-spaces.
example:
select substr(tempcol, -- string
instr(tempcol, ' ', 1), -- location of first white-space
instr(tempcol, ' ', 1, 2) - instr(tempcol, ' ', 1)) -- length until next space
from dual
another solution is using regexp_substr (but it might be harder on performance if you have a lot of rows):
SELECT REGEXP_SUBSTR (tempcol, '(\S*)(\s*)', 1, 2)
FROM dual;
edit: fixed the regular expression to include expressions that don't have space after the parsed text. sorry about that.. ;)

Get rows that contain only certain characters

I want to get only those rows that contain ONLY certain characters in a column.
Let's say the column name is DATA.
I want to get all rows where in DATA are ONLY (must have all three conditions!):
Numeric characters (1 2 3 4 5 6 7 8 9 0)
Dash (-)
Comma (,)
For instance:
Value "10,20,20-30,30" IS OK
Value "10,20A,20-30,30Z" IS NOT OK
Value "30" IS NOT OK
Value "AAAA" IS NOT OK
Value "30-" IS NOT OK
Value "30," IS NOT OK
Value "-," IS NOT OK
Try patindex:
select * from(
select '10,20,20-30,30' txt union
select '10,20,20-30,40' txt union
select '10,20A,20-30,30Z' txt
)x
where patindex('%[^0-9,-]%', txt)=0
For you table, try like:
select
DATA
from
YourTable
where
patindex('%[^0-9,-]%', DATA)=0
As per your new edited question, the query should be like:
select
DATA
from
YourTable
where
PATINDEX('%[^0-9,-]%', DATA)=0 and
PATINDEX('%[0-9]%', LEFT(DATA, 1))=1 and
PATINDEX('%[0-9]%', RIGHT(DATA, 1))=1 and
PATINDEX('%[,-][-,]%', DATA)=0
Edit: Your question was edited, so this answer is no longer correct. I won't bother updating it since someone else already has updated theirs. This answer does not fulfil the condition that all three character types must be found.
You can use a LIKE expression for this, although it's slightly convoluted:
where data not like '%[^0123456789,!-]%' escape '!'
Explanation:
[^...] matches any character that is not in the ... part. % matches any number (including zero) of any character. So [^0123456789-,] is the set of characters that you want to disallow.
However: - is a special character inside of [], so we must escape it, which we do by using an escape character, and I've chosen !.
So, you match rows that do not contain (not like) any character that is not in your disallowed set.
Use option with PATINDEX and LIKE logic operator
SELECT *
FROM dbo.test70
WHERE PATINDEX('%[A-Z]%', DATA) = 0
AND PATINDEX('%[0-9]%', DATA) > 0
AND DATA LIKE '%-%'
AND DATA LIKE '%,%'
Demo on SQLFiddle
As already mentioned u can use a LIKE expression but it will only work with some minor modifications, otherwise too many rows will be filtered out.
SELECT * FROM X WHERE T NOT LIKE '%[^0-9!-,]%' ESCAPE '!'
see working example here:
http://sqlfiddle.com/#!3/474f5/6
edit:
to meet all 3 conditions:
SELECT *
FROM X
WHERE T LIKE '%[0-9]%'
AND T LIKE '%-%'
AND T LIKE '%,%'
see: http://sqlfiddle.com/#!3/86328/1
Maybe not the most beautiful but a working solution.