sql server all characters to right of first hyphen - sql

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)

Related

Regex for a single space then numbers

I am using this an an sql query to return just the first numbers out of a string and nothing else. I need it to do that for the first match that starts with a space.
so
hello world56 12345
would return only 12345
right now I get the 56
SUBSTRING(s.Description, PATINDEX('%[0-9]%',s.Description), PATINDEX('%[^0-9]%',SUBSTRING(s.Description, PATINDEX('%[0-9]%',s.Description), LEN(s.Description)))-1);
--test
DECLARE #Str nvarchar(1000)
SET #Str = 'ANDERSON, LEILANI M - MEDICAL ONCOLOGY 40225 (DFCI)'
SELECT SUBSTRING(#str,
PATINDEX(' %[0-9]%',#str)+1,
PATINDEX('%[^0-9]%',
SUBSTRING(#str,
PATINDEX(' %[0-9]%',#str)+1,
LEN(#str)))-1);
Put a space at the beginning of the pattern, and then add 1 to the index that it returns to get the position of the digit after the space.
SUBSTRING(s.Description,
PATINDEX('% [0-9]%',s.Description)+1,
PATINDEX('%[^0-9]%',
SUBSTRING(s.Description,
PATINDEX('% [0-9]%',s.Description)+1,
LEN(s.Description))
+ ' ')-1);
I append a space in the second PATINDEX() call so that it will work correctly if the number is at the end of the string.
DEMO
You may use the following select statement with substring, charindex, and patindex :
select substring(q.str, charindex(' ',q.str)+1,len(q.str)) as "Result"
from
(
select substring(Description,patindex('%[0-9]%',Description),len(Description)) str
from tab
) q;
Result
------
12345
Rextester Demo

Get substring after and before '-' character

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'

SQL: how to select a substring between special characters

My string looks something like this:
\\\abcde\fghijl\akjfljadf\\
\\xyz\123
I want to select everything between the 1st set and next set of slashes
Desired result:
abcde
xyz
EDITED: To clarify, the special character is always slashes - but the leading characters are not constant, sometimes there are 3 slashes and other times there are only 2 slashes, followed by texts, and then followed by 1 or more slashes, some more texts, 1 or more slash, so on and so forth. I'm not using any adapter at all, just looking for a way to select this substring in my SQL query
Please advise.
Thanks in advance.
You could do a cross join to find the second position of the backslash. And then, use substring function to get the string between 2nd and 3rd backslash of the text like this:
SELECT substring(string, 3, (P2.Pos - 2)) AS new_string
FROM strings
CROSS APPLY (
SELECT (charindex('\', replace(string, '\\', '\')))
) AS P1(Pos)
CROSS APPLY (
SELECT (charindex('\', replace(string, '\\', '\'), P1.Pos + 1))
) AS P2(Pos)
SQL Fiddle Demo
UPDATE
In case, when you have unknown number of backslashes in your string, you could just do something like this:
DECLARE #string VARCHAR(255) = '\\\abcde\fghijl\akjfljadf\\'
SELECT left(ltrim(replace(#string, '\', ' ')),
charindex(' ',ltrim(replace(#string, '\', ' ')))-1) AS new_string
SQL Fiddle Demo2
Use substring, like this (only works for the specified pattern of two slashes, characters, then another slash):
declare #str varchar(100) = '\\abcde\cc\xxx'
select substring(#str, 3, charindex('\', #str, 3) - 3)
Replace #str with the column you actually want to search, of course.
The charindex returns the location of the first slash, starting from the 3rd character (i.e. skipping the first two slashes). Then the substring returns the part of your string starting from the 3rd character (again, skipping the first two slashes), and continuing until just before the next slash, as determined by charindex.
Edit: To make this work with different numbers of slashes at the beginning, use patindex with regex to find the first alphanumeric character, instead of hardcoding that it should be the third character. Example:
declare #str varchar(100) = '\\\1Abcde\cc\xxx'
select substring(#str, patindex('%[a-zA-Z0-9]%', #str), charindex('\', #str, patindex('%[a-zA-Z0-9]%', #str)) - patindex('%[a-zA-Z0-9]%', #str))
APH's solution works better if your string always follows the pattern as described. However this will get the text despite the pattern.
declare #str varchar(100) = '\\abcde\fghijl\akjfljadf\\'
declare #srch char(1) = '\'
select
SUBSTRING(#str,
(CHARINDEX(#srch,#str,(CHARINDEX(#srch,#str,1)+1))+1),
CHARINDEX(#srch,#str,(CHARINDEX(#srch,#str,(CHARINDEX(#srch,#str,1)+1))+1))
- (CHARINDEX(#srch,#str,(CHARINDEX(#srch,#str,1)+1))+1)
)
Sorry for the formatting.
Edited to correct user paste error. :)

Want to pull variable info from a Comments section

I am querying a table that contains a comments section. The comments section can contain part numbers of variable lengths. If, within the comments section I ensure that the part numbers are wrapped in quotes ("partnumberA"), is it possible query that field to pull everything in between the quotes (even if the part numbers could vary in length)?
Production notes are stored in an NVARCHAR field. Here is some sample data:
3/6/2015 (blujo) - "3490-0001023-02" PO46709 Due 3/10 (RW24718)
You can use a combination of substring and charindex functions.
declare #Comments varchar(50)
set #Comments = '3/6/2015 (blujo) - "3490-0001023-02" PO46709 Due 3/10 (RW24718)'
select substring(#Comments,
charindex('"',#Comments)+1,
charindex('"',#Comments,
charindex('"',#Comments)+1)-charindex('"',#Comments)-1)
The first charindex finds the first quote and starts on the following character. The second and third charindex finds the next quote after the first.
If the length of the part number is standard (say 6 characters), you could always try a SUBSTRING, CHARINDEX mix:
SELECT SUBSTRING(Comments, CHARINDEX('"', Comments) - 1, CHARINDEX('"', Comments) + 6)
FROM Table
This would start your substring just before the first double quote, and go until it finds the last double quote.
You can use CROSS APPLY to select the indices of successive occurences of the " character in your NVARCHAR field. Having these indices at hand, you can use SUBSTRING to extract the required part of the field:
SELECT SUBSTRING(ProductionNotes, First.x + 1, Second.x - First.x - 1)
FROM MyTable
CROSS APPLY (SELECT CHARINDEX('"', ProductionNotes)) AS First(x)
CROSS APPLY (SELECT CHARINDEX('"', ProductionNotes, First.x + 1)) AS Second(x)
First.x is the index of the 1st occurence of " in ProductionNotes field. The second occurence is located by feeding the previous index + 1, i.e. First.x + 1, as the start_location of CHARINDEX.
Here's a sample using a variable. Of course your query would reference a table column instead:
declare #x varchar(256) = '3/6/2015 (blujo) - "3490-0001023-02" PO46709 Due 3/10 (RW24718)';
select
substring(
#x,
charindex('"', #x) + 1,
charindex('"', #x, charindex('"', #x) + 1) - charindex('"', #x) - 1
)

need to replace some underscores with hypens

I have a column with value
AAA_ZZZZ_7890_10_28_2014_123456.jpg
I need to replace the middle underscores so that it displays it as date i.e.
AAA_ZZZZ_7890_10-28-2014_123456.jpg
Can some one please suggest a simple update query for this.
The Number of Underscores would be same for all the values in the column but the length will vary for example some can have
AAA_q10WRQ_001_10_28_2014_12.jpg
The following should do it:
http://sqlfiddle.com/#!3/d41d8/30384/0
declare #filename varchar(64) = 'AAA_ZZZZ_7890_10_28_2014_123456.jpg'
declare #datepattern varchar(64) = '%[_][0-1][0-9][_][0-3][0-9][_][1-2][0-9][0-9][0-9][_]%'
select
filename,
substring(filename,1,datepos+2)+'-'+
substring(filename,datepos+4,2)+'-'+
substring(filename,datepos+7,1000)
from
(
select
#filename filename,
patindex(#datepattern,#filename)
as datepos
) t
;
Resulting in
AAA_ZZZZ_7890_10-28-2014_123456.jpg
Caveats to watch out for:
It is important to exactly define how you find the date. In my definition it is MM_DD_YYYY surrounded by further two underscores, and I check that the first digits of M,D,Y are 0-1,0-3,1-2 respectively (i.e. I do NOT check if month is e.g. 13.) -- of course we assume that there is only one such string in any file name.
datepos actually finds the position of the underscore before the date -- this is not an issue if taken into account in the indexing of substring.
in the 3rd substring the length cannot be NULL or infinity and I couldn't get LEN() to work in SQL Fiddle so I dirty hardcoded a large enough number (1000). Corrections to this are welcome.
Try this (assuming that the DATE portion always starts at the same character index)
declare #string varchar(64) = 'AAA_ZZZZ_7890_10_28_2014_123456.jpg'
select replace(#string, reverse(substring(reverse(#string), charindex('_', reverse(#string), 0) + 1, 10)), replace(reverse(substring(reverse(#string), charindex('_', reverse(#string), 0) + 1, 10)), '_', '-'))
If there are exactly 6 _ then for the first
select STUFF ( 'AAA_ZZZZ_7890_10_28_2014_123456.jpg' , CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', 0 ) + 1 ) + 1 ) + 1 ) , 1 , '-' )