Get substring after and before '-' character - sql

I have this kind of strings in a table:
AM-65-800
AM-75/86-650
D-27-600
What I'm trying to do is to get only the middle part, for example:
65
75/86
27
Basically the substring after and before the '-' Char
I tried this (from an example in here):
SELECT SUBSTRING(Product.Name, LEN(LEFT(Product.[Name], CHARINDEX ('-', Product.[Name]))) + 1, LEN(Product.[Name]) - LEN(LEFT(Product.[Name], CHARINDEX ('-', Product.[Name]))) - LEN(RIGHT(Product.[Name], LEN(Producto.[Name]) - CHARINDEX ('-', Product.[Name]))) - 1)
FROM Product
But it gives me this error:
[42000] [Microsoft][SQL Server Native Client 10.0][SQL Server]Invalid length parameter passed to the LEFT or SUBSTRING function. (537)
Being honest, I don't know how to solve the error because I don't understand the solution from the example. what can I do?
Thanks.

One option is ParseName()
Example
Declare #S varchar(max)='AM-65-800'
Select parsename(replace(#S,'-','.'),2)
Returns
65

Use SUBSTRING with start and lengths calculated based on position of the '-':
SELECT SUBSTRING('ABC-65-DEF',
CHARINDEX('-', 'ABC-65-DEF') + 1,
CHARINDEX('-', 'ABC-65-DEF', CHARINDEX('-', 'ABC-65-DEF') + 1) - CHARINDEX('-', 'ABC-65-DEF') - 1)
Basically, it finds the first instance of the '-' (CHARINDEX('-', 'ABC-65-DEF')) and then the second instance of '-' (CHARINDEX('-', 'ABC-65-DEF', CHARINDEX('-', 'ABC-65-DEF') + 1)) and grabs the substring inbetween.

This will work to find the middle part on older SQL Servers up to and including 2008.
DECLARE #SomeText VARCHAR(100) = 'AM-75/86-650'
SELECT LEFT(RIGHT(#SomeText, LEN(#SomeText) - CHARINDEX('-', #SomeText)),
CHARINDEX('-', RIGHT(#SomeText, LEN(#SomeText) - CHARINDEX('-', #SomeText)))-1)
Returns: '75/86'

Related

is there a way to use a mid-style function in sql like you can for excel?

I have the following string of characters:
594074_Ally_Financial_TokioMarine_MD_SLDET_20210101_20211130_20211208
I am attempting to extract everything after the first '_' but before the '_TokioMarine', so the final string will look like:
Ally_Financial
Is this possible to do with SQL? I attempted but it was pulling the incorrect characters. I cant get the ones in between the values specified.
SELECT
#CurPolicyHolder = Right( DFH.FileName, CHARINDEX('_', DFH.FileName) - 1)
To extract everything between the first _ character and the _TokyoMarine string, you can use:
SELECT
#CurPolicyHolder = SUBSTRING(DFH.FileName, CHARINDEX('_', DFH.FileName) + 1,
CHARINDEX('_TokioMarine', DFH.FileName) - CHARINDEX('_', DFH.FileName) - 1)
SUBSTRING (Transact-SQL)
CHARINDEX (Transact-SQL)

Get text after second occurrence of a specific character

I have a column with data like this:
firstNameLetter_surname_numericCode
For example:
m_johnson_1234
I need to extract the numeric code. I've tried with SUBSTRING function but I just get:
surname_numericCode
This is the code I've used:
SET number = substring(t2.code, charindex('_', t2.code, 2) + 1, len(t2.code))
How can I get just the numeric code?
Heres a one-liner for you
select right('m_johnson_1234', charindex('_', reverse('m_johnson_1234') + '_') - 1)
Call the CHARINDEX function twice:
SELECT SUBSTRING(
code,
NULLIF(CHARINDEX('_', code, NULLIF(CHARINDEX('_', code), 0) + 1), 0) + 1,
LEN(code)
)
FROM (VALUES
('a_b_c'),
('a_b')
) x(code)
One method is to look for the first _ in the reversed string:
select col,
stuff(col, 1, len(col) - charindex('_', reverse(col)) + 1, '') as numericCode
from (values ('firstNameLetter_surname_numericCode')) v(col);
If the numeric code is really a number -- and no other numbers start the preceding values -- then you can use patindex():
select col,
stuff(col, 1, patindex('%[_][0-9]%', col), '') as numericCode
from (values ('firstNameLetter_surname_0000')) v(col);
The SUBSTR and INSTR functions can be combined to get you the numeric code.
SELECT SUBSTR('m_johnson_1234', INSTR('m_johnson_1234', '_', 1, 2)+1) FROM TABLE;
For the start_pos argument use INSTR to start at the beginning of the string, and find the index of the second instance of the '_' character. Then use that to start one position after and read to the end of the string.
If you need the result to be numeric instead of still a string, then wrap the SUBSTR() in a TO_NUMBER() function.
Late answer, and just because I didn't see PARSENAME() mentioned.
Example
Select parsename(replace(t2.code,'_','.'),1)
From YourTable

SQL Server Query Output with sql scenario replace values with 'x' [duplicate]

This question already has answers here:
Replacing certain character in email addresses with '*' in an SQL query
(3 answers)
Closed 6 years ago.
I have one col in my table like:
COL
Kiyara#ymail.com
Akira#zmail.com
I want my output something like this:
COL
Kxxxxx#ymail.com
Axxxx#zmail.com
iyara replaced with 5x's(xxxxx) and 'kira' with 4x's(xxxx)
There's probably a better way to do it that this, but this achieves what you're after:
DECLARE #email NVARCHAR(50) = 'Kiyara#ymail.com';
SELECT LEFT(#email, 1) + REPLICATE('X',
LEN(SUBSTRING(#email, 2,
CHARINDEX('#', #email) - 1)))
+ SUBSTRING(#email, CHARINDEX('#', #email), LEN(#email));
-- Result: KXXXXXX#ymail.com
This uses the REPLICATE() method, which according to the docs online starts with SQL Server 2008.
REPLICATE (Transact-SQL)
Repeats a string value a specified number of times.
REPLICATE ( string_expression ,integer_expression )
SELECT LEFT(col, 1) + RIGHT('xxxxxxxxxxxxxxxx', CHARINDEX('#', col) - 2) +
SUBSTRING(col, CHARINDEX('#', col), LEN(col) - CHARINDEX('#', col) + 1);
Explanation:
Take Kiyara#ymail.com as an example, and each piece of my query is shown here.
K LEFT(col, 1)
xxxxx RIGHT('xxxxxxxxxxxxxxxx', CHARINDEX('#', col) - 2)
#ymail.com SUBSTRING(col, CHARINDEX('#', col), LEN(col) - CHARINDEX('#', col) + 1)
Note that you can replace the call to RIGHT() with a string of x's long enough to match your longest expected email name.
Try it's
select substring('Akira#zmail.com',1,1) + REPLICATE('x',charindex('#','Akira#zmail.com')) + SUBSTRING('Akira#zmail.com',charindex('#','Akira#zmail.com'),200)
Change the email by column or whatever you want
declare #n nvarchar(max)
set #n='Kiyara#ymail.com'
select concat(substring(#n,1,1),replicate('X',len( substring(#n,2,charindex('#',#n,1)-2))),SUBSTRING(#n,charindex('#',#n),200))
In this with the help o substring you have found first letter ans then rest of he letter til # i.e iyara is searched using charindex ans substring,which will be converted into 'x' using replicate function and then rest id printed.

sql server all characters to right of first hyphen

In SQL Server 2014, how can I extract all characters to the right of the first hyphen in a field where the first hyphen will have many combinations following it.
example 1:
Aegean-1GB-7days-COMP
desired result:
1GB-7days-COMP
example 2:
Aegean-SchooliesSpecial-7GB
desired result:
SchooliesSpecial-7GB
example 3:
AkCityOaks-1Day-3GB
desired result:
1Day-3GB
Using CHARINDEX AND SUBSTRING would work:
DECLARE #HTXT as nvarchar(max)
SET #HTXT='lkjhgf-wtrfghvbn-jk87fry--jk'
SELECT SUBSTRING(#HTXT, CHARINDEX('-', #HTXT) + 1, LEN(#HTXT))
Result:
wtrfghvbn-jk87fry--jk
You can use a combination of CharIndex and 'SubString' to get the desired result.
When you do this, you will get the location of the first hyphen starting from the first character.
CharIndex ('Aegean-1GB-7days-COMP', '-', 1)
Then cutting the string is easy
Select
SubString (
'Aegean-1GB-7days-COMP',
CharIndex ('-', 'Aegean-1GB-7days-COMP', 1) + 1,
Len('Aegean-1GB-7days-COMP') - CharIndex ('-', 'Aegean-1GB-7days-COMP', 1)
)
Since your data is most likely in a column, I would change this to
Select
SubString (
YourColumnName,
CharIndex ('-', YourColumnName, 1) + 1,
Len(YourColumnName) - CharIndex ('-', YourColumnName, 1)
)
From YourTableName
If you want to match -- instead of -, then look at PatIndex`
Read Here about CharIndex
Read Here about PatIndex
Read Here about SubString
Hi you can use PATINDEX and SUBSTRING like this:
DECLARE #Text NVARCHAR(4000)
DECLARE #StartPos int
SET #StartPos = PATINDEX('%-%',#Text) + 1
RETURN SUBSTRING(#Text,#StartPos,LEN(#Text)-#StartPos)
Or in one:
SUBSTRING([Text],PATINDEX('%A%',[Text]) + 1, LEN([Text]) - PATINDEX('%A%',[Text]) + 1)

How to get a id from a url using SQL QUERY. The ID changes dynamically. the database is Sql server 2008

I have url like:
http://mysites.xyz.com/_layouts/ng/ActivityStream.aspx/id/2624D92223261D370D7287C9E83CAEEA/Activity%20Stream%20Post.
I need to get the 2624D92223261D370D7287C9E83CAEEA. But not able to do so. my current query is
SUBSTRING(#URL2,LEN('http://mysites.xyz.com/_layouts/ng/ActivityStream.aspx/id/'),LEN(#URL2)-LEN('http://mysites.xyz.com/_layouts/ng/ActivityStream.aspx/id/')- CHARINDEX('/',REVERSE(#URL2))))
Please suggest.
Try this:
SELECT SUBSTRING(
#URL2,
CHARINDEX('/id/', #URL2)+4,
CHARINDEX('/', #URL2, CHARINDEX('/id/', #URL2)+5)
- (CHARINDEX('/id/', #URL2)+4))
Note: This assumes that the id is always followed by at least one more slash.
Breakdown:
The first argument of the substring is the string that contains the full expression.
The second one is the first index after /id/.
The third one is the desired length - calculated by the first index of / after /id/ - the first index after /id/.
update
To cope with strings that does not contain a slash after the id value, use case:
SELECT SUBSTRING(
#URL,
CHARINDEX('/id/', #URL)+4,
CASE WHEN CHARINDEX('/', #URL, CHARINDEX('/id/', #URL)+5) > 0 THEN
CHARINDEX('/', #URL, CHARINDEX('/id/', #URL)+5)
- (CHARINDEX('/id/', #URL)+4)
ELSE
LEN(#URL)
END
)
If the structure is always the same then you can try:
SELECT REPLACE(RIGHT(#s, LEN(#s) - 58), '/Activity%20Stream%20Post', '')
or:
SELECT REPLACE(REPLACE(#s,'/Activity%20Stream%20Post', ''), 'http://mysites.xyz.com/_layouts/ng/ActivityStream.aspx/id/', '')