Split string and take last element - sql

I have a table with this values:
Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx
OurStory/MeettheFoodieandtheMD.aspx
TheFood/OurMenu.aspx
I want to get this
Diet.aspx
MeettheFoodieandtheMD.aspx
OurMenu.aspx
How can i do this?

The way to do it in SQL :
SELECT SUBSTRING( string , LEN(string) - CHARINDEX('/',REVERSE(string)) + 2 , LEN(string) ) FROM SAMPLE;
JSFiddle here http://sqlfiddle.com/#!3/41ead/11

SELECT REVERSE(LEFT(REVERSE(columnName), CHARINDEX('/', REVERSE(columnName)) - 1))
FROM tableName
SQLFiddle Demo
ORHER SOURCE(s)
REVERSE
LEFT
CHARINDEX

Please try:
select url,(CASE WHEN CHARINDEX('/', url, 1)=0 THEN url ELSE RIGHT(url, CHARINDEX('/', REVERSE(url)) - 1) END)
from(
select 'Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx' as url union
select 'OurStory/MeettheFoodieandtheMD.aspx' as url union
select 'MeettheFoodieandtheMD.aspx' as url
)xx

Try this. It's easier.
SELECT RIGHT(string, CHARINDEX('/', REVERSE(string)) -1) FROM TableName

SELECT REVERSE ((
SELECT TOP 1 value FROM STRING_SPLIT(REVERSE('Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx'), '/')
)) AS fName
Result: Diet.aspx
Standard STRING_SPLIT does not allow to take last value.
The trick is to reverse the string (REVERSE) before splitting with STRING_SPLIT, get the first value from the end (TOP 1 value) and then the result needs to be reversed again (REVERSE) to restore the original chars sequence.
Here is the common approach, when working with SQL table:
SELECT REVERSE ((
SELECT TOP 1 VALUE FROM STRING_SPLIT(REVERSE(mySearchString), '/')
)) AS myLastValue
FROM myTable

A slightly more compact way of doing this (similar to ktaria's answer but in SQL Server) would be
SELECT TOP 1 REVERSE(value) FROM STRING_SPLIT(REVERSE(fullPath), '/') AS fileName

The equivalent for PostgreSQL:
SELECT reverse(split_part(reverse(column_name), '/', 1));

Please try the code below:
SELECT SUBSTRING( attachment, LEN(attachment)
- CHARINDEX('/', REVERSE(attachment)) + 2, LEN(attachment) ) AS filename
FROM filestable;

more simple and elegant :
select reverse(SPLIT_PART(reverse('Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx'), '/',1))

You can try this too
( SELECT TOP(1) value
FROM STRING_SPLIT(#string, '/')
ORDER BY CHARINDEX('/' + value + '/', '/' + #string+ '-') DESC)

I corrected jazzytomato's solution for single character tokens (D) and for single tokens (Diet.aspx)
SELECT SUBSTRING( string , LEN(string) - CHARINDEX('/','/'+REVERSE(string)) + 2 , LEN(string) ) FROM SAMPLE;

The easiest way in MySQL:
SELECT SUBSTRING_INDEX(string, '/', -1) FROM SAMPLE;

I have more simple solve
SELECT SUBSTRING_INDEX(string, 'SUBSTRING_INDEX(string, '/', -1)', 1) FROM SAMPLE;

reverse(SUBSTRING(reverse(yourString),0,CHARINDEX('/',reverse(yourString)))) as stringLastPart

Create Table #temp
(
ID int identity(1,1) not null,
value varchar(100) not null
)
DECLARE #fileName VARCHAR(100);
INSERT INTO #temp(value) SELECT value from STRING_SPLIT('C:\Users\Documents\Datavalidation\Input.csv','\')
SET #fileName=(SELECT TOP 1 value from #temp ORDER BY ID DESC);
SELECT #fileName AS File_Name;
DROP TABLE #temp

Related

How do I select a substring from two different patindex?

I have many different types of string, but they all follow the two same patterns:
ABC123-S-XYZ789
ABC123-P-XYZ789
QUESTION 1:
I know how I can extract the first part: ABC123
But how do I extract the second part??? XYZ789
QUESTION 2:
I can't tell beforehand if the string follows the -S- pattern or the -P- pattern, it can be different each time. Anyone who know how I can solve this?
Thanks! / Sophie
You can try following code:
SELECT CASE WHEN #a LIKE '%-S-%' THEN right(#a, CHARINDEX('-S-', #a)-1)
WHEN #a LIKE '%-P-%' THEN right(#a, CHARINDEX('-P-', #a)-1)
ELSE NULL END AS 'ColName'
FROM tablename
Is this what you need?
DECLARE #Input VARCHAR(100) = 'ABC123-S-XYZ789'
SELECT
FirstPart = SUBSTRING(
#Input,
1,
CHARINDEX('-', #Input) - 1),
SecondPart = SUBSTRING(
#Input,
LEN(#Input) - CHARINDEX('-', REVERSE(#Input)) + 2,
100),
Pattern = CASE
WHEN #Input LIKE '%-S-%' THEN 'S'
WHEN #Input LIKE '%-P-%' THEN 'P' END
You can use parsename() if the string has always this kind of parts such as ABC123-S-XYZ789
select col, parsename(replace(col, '-', '.'), 1)
However, the parsename() requires the SQL Server+12 if not then you can use reverse()
select col, reverse(left(reverse(col), charindex('-', reverse(col))-1))
If you're using SQL Server 2016 or newer, you can use STRING_SPLIT
CREATE TABLE #temp (string VARCHAR(100));
INSERT #temp VALUES ('ABC123-S-XYZ789'),('ABC123-P-XYZ789');
SELECT *, ROW_NUMBER() OVER (PARTITION BY string ORDER BY string)
FROM #temp t
CROSS APPLY STRING_SPLIT(t.string, '-');
I can't tell beforehand if the string folllows the -S- pattern or the -P- pattern
You can then use a CTE to get a specific part of the string:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY string ORDER BY string) rn
FROM #temp t
CROSS APPLY STRING_SPLIT(t.string, '-')
)
SELECT * FROM cte WHERE rn = 2

Select text from between two characters in string

I have data in database an example of data below
folder/subfolder/file/doc
folder/subfolder/doc
how do I get the 1st instance of characters from between the '/'
I want to extract 'folder/subfolder'
I have tried the following but not what I need. this gets 'folder/'
LEFT([Cat], CHARINDEX('/', [Cat]) ) as 'doc_cat',
and the below gets the last part
RIGHT([Cat], CHARINDEX('/', [Cat]) ) as 'doc_cat2',
I want to get the 1st part of and second part of string
Here is one method:
select left(doc_cat_1, charindex('/', doc_cat_1) - 1)
from t cross apply
(select stuff(cat, 1, charindex('/', cat), '') as doc_cat_1
) v1;
The string handling capabilities of SQL Server are pretty lousy. Apply at least makes it easier to handle intermediate results.
You can use LEFT and CHARINDEX
LEFT([Cat],charindex('/',[Cat],charindex('/',[Cat])+1)-1) AS 'doc_cat'
One more way to accomplish using XML -
declare #s table(patterns nvarchar(100))
insert into #s
values ('folder/subfolder/file/doc'), ('folder/subfolder/doc'),('folder/subfolder')
select cast(concat('<x>', REPLACE(patterns, '/', '</x><x>'), '</x>') as xml).value('/x[1]','varchar(100)') + '/'
+ cast(concat('<x>', REPLACE(patterns, '/', '</x><x>'), '</x>') as xml).value('/x[2]','varchar(100)')
from #s
If you're on SQL 2016 or newer, you could use STRING_SPLIT()
WITH cte AS (
SELECT cat, value, ROW_NUMBER() OVER (PARTITION BY cat ORDER BY cat) rn
FROM someTable CROSS APPLY
STRING_SPLIT(cat,'/')
)
SELECT cat, value FROM cte WHERE rn = 2;
The advantage here is that rn could be any number you need.
Fiddle here.

I want to remove part of string from a string

Thank you in advance.
I want to remove string after . including ., but length is variable and string can be of any length.
1)Example:
Input:- SCC0204.X and FRK0005.X and RF0023.X and ADF1010.A and HGT9010.V
Output: SCC0204 and FRK0005 and RF0023 and ADF1010.A and HGT9010.V
I tried using the charindex but as the length keeps on changing i wasn't able to do it. I want to trim the values with ending with only X
Any help will be greatly appreciated.
Assuming there is only one dot
UPDATE TABLE
SET column_name = left(column_name, charindex('.', column_name) - 1)
For SELECT
select left(column_name, charindex('.', column_name) - 1) AS col
from your_table
Hope this helps. The code only trims the string when the value has a decimal "." in it and if that value is equal to .X
;WITH cte_TestData(Code) AS
(
SELECT 'SCC0204.X' UNION ALL
SELECT 'FRK0005.X' UNION ALL
SELECT 'RF0023.X' UNION ALL
SELECT 'ADF1010.A' UNION ALL
SELECT 'HGT9010.V' UNION ALL
SELECT 'SCC0204' UNION ALL
SELECT 'FRK0005'
)
SELECT CASE
WHEN CHARINDEX('.', Code) > 0 AND RIGHT(Code,2) = '.X'
THEN SUBSTRING(Code, 1, CHARINDEX('.', Code) - 1)
ELSE Code
END
FROM cte_TestData
If the criteria is only to replace remove .X then probably this should also work
;WITH cte_TestData(Code) AS
(
SELECT 'SCC0204.X' UNION ALL
SELECT 'FRK0005.X' UNION ALL
SELECT 'RF0023.X' UNION ALL
SELECT 'ADF1010.A' UNION ALL
SELECT 'HGT9010.V' UNION ALL
SELECT 'SCC0204' UNION ALL
SELECT 'FRK0005'
)
SELECT REPLACE (Code,'.X','')
FROM cte_TestData
Use LEFT String function :
DECLARE #String VARCHAR(100) = 'SCC0204.XXXXX'
SELECT LEFT(#String,CHARINDEX('.', #String) - 1)
I think your best bet here is to create a function that parses the string and uses regex. I hope this old post helps:
Perform regex (replace) in an SQL query
However, if the value you need to trim is constantly ".X", then you should use
select replace(string, '.x', '')
Please check the below code. I think this will help you.
DECLARE #String VARCHAR(100) = 'SCC0204.X'
IF (SELECT RIGHT(#String,2)) ='.X'
SELECT LEFT(#String,CHARINDEX('.', #String) - 1)
ELSE
SELECT #String
Update: I just missed one of the comments where the OP clarifies the requirement. What I put together below is how you would deal with a requirement to remove everything after the first dot on strings ending with X. I leave this here for reference.
;WITH cte_TestData(Code) AS
(
SELECT 'SCC0204.X' UNION ALL -- ends with '.X'
SELECT 'FRK.000.X' UNION ALL -- ends with '.X', contains multiple dots
SELECT 'RF0023.AX' UNION ALL -- ends with '.AX'
SELECT 'ADF1010.A' UNION ALL -- ends with '.A'
SELECT 'HGT9010.V' UNION ALL -- ends with '.V'
SELECT 'SCC0204.XF' UNION ALL -- ends with '.XF'
SELECT 'FRK0005' UNION ALL -- totally clean
SELECT 'ABCX' -- ends with 'X', not dots
)
SELECT
orig_string = code,
newstring =
SUBSTRING
(
code, 1,
CASE
WHEN code LIKE '%X'
THEN ISNULL(NULLIF(CHARINDEX('.',code)-1, -1), LEN(code))
ELSE LEN(code)
END
)
FROM cte_TestData;
FYI - SQL Server 2012+ you could simplify this code like this:
SELECT
orig_string = code,
newstring =
SUBSTRING(code, 1,IIF(code LIKE '%X', ISNULL(NULLIF(CHARINDEX('.',code)-1, -1), LEN(code)), LEN(code)))
FROM cte_TestData;
With SUBSTRING you can achieve your requirements by below code.
SELECT SUBSTRING(column_name, 0, CHARINDEX('.', column_name)) AS col
FROM your_table
If you want to remove fixed .X from string you can also use REPLACE function.
SELECT REPLACE(column_name, '.X', '') AS col

Extract one value from a column containing multiple delimited values

How can I get the value from the sixth field in the following column? I am trying to get the 333 field:
ORGPATHTXT
2123/2322/12323/111/222/333/3822
I believe I have to use select substring, but am unsure how to format the query
Assuming SQL Server
The easiest way I can think of is create a Split function that splits based on '/' and you extract the sixth item like below
declare #text varchar(50) = '2123/2322/12323/111/222/333/3822'
select txt_value from fn_ParseText2Table(#text, '/') t where t.Position = 6
I used the function in this url. See it worked at SQLFiddle
Try this - for a string variable or wrap into a function to use with a select query (Sql-Demo)
Declare #s varchar(50)='2123/2322/12323/111/222/333/3822'
Select #s = right(#s,len(#s)- case charindex('/',#s,1) when 0 then len(#s)
else charindex('/',#s,1) end)
From ( values (1),(2),(3),(4),(5)) As t(num)
Select case when charindex('/',#s,1)>0 then left(#s,charindex('/',#s,1)-1)
else #s end
--Results
333
I'd like to offer a solution that uses CROSS APPLY to split up any delimited string in MSSQL and ROW_NUMBER() to return the 6th element. This assumes you have a table with ORGPATHTXT as a field (it can easily be converted to work without the table though):
SELECT ORGPATHTXT
FROM (
SELECT
Split.a.value('.', 'VARCHAR(100)') AS ORGPATHTXT,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY (SELECT 1)) RN
FROM
(SELECT ID, CAST ('<M>' + REPLACE(ORGPATHTXT, '/', '</M><M>') + '</M>' AS XML) AS String
FROM MyTable
) AS A
CROSS APPLY String.nodes ('/M') AS Split(a)
) t
WHERE t.RN = 6;
Here is some sample Fiddle to go along with it.
Good luck.
For sql, you can use
declare #string varchar(65) = '2123/2322/12323/111/222/333/3822'
select substring(string,25,27) from table_name
If you are using MySQL, then you can use:
select substring_index(orgpathtxt, '/', 6)
Let me just say that it is less convenient in most other databases.
Also you can use option with dynamic management function sys.dm_fts_parser
DECLARE #s nvarchar(50) = '2123/2322/12323/111/222/333/3822'
SELECT display_term
FROM sys.dm_fts_parser('"'+ #s + '"', 1033, NULL, 0)
WHERE display_term NOT LIKE 'nn%' AND occurrence = 6

How to extract substring in SQL Server

I have a field with something like okbogkbogkbokgbokgobkgobkofkgbokfgbo&name=fokdofkd&okfaos
I'd like to extract the name = value from the data.
How can I do that using SQL Server 2008 in efficient way?
thank you
Try this
;
With MyTable as
(
SELECT 'okbogkbogkbokgbokgobkgobkofkgbokfgbo&name=fokdofkd&okfaos' FullString
UNION
SELECT 'fkgbokfgbo&name=fokdofkd&okfaos' FullString
UNION
SELECT 'okbogkbogkbokgbok' FullString
),
PatternIndex as
(
Select
FullString + '&' FullString,
CharIndex ('&name=', FullString) + 1 LocationOfEqualSign,
CharIndex ('&', FullString, CharIndex ('&name=', FullString)+1) as NextBreak
from MyTable
),
SplitNameValue AS
(
Select
FullString,
CASE
WHEN NextBreak <> 0 THEN
SubString (FullString, LocationOfEqualSign, NextBreak-LocationOfEqualSign)
ELSE '' END
as NameValuePair
From PatternIndex
)
SELECT *
FROM SplitNameValue
Returns
FullString NameValuePair
--------------------------------------------------------- ---------------------------------------------------------
fkgbokfgbo&name=fokdofkd&okfaos name=fokdofkd
okbogkbogkbokgbok
okbogkbogkbokgbokgobkgobkofkgbokfgbo&name=fokdofkd&okfaos name=fokdofkd
(3 row(s) affected)
SELECT 'name=' + SUBSTRING(field, CHARINDEX('name=', field), CHARINDEX('&', SUBSTRING(field, CHARINDEX('name=' ,field))))
Something along the lines of...
select substring(ColumnName, charindex('name=',ColumnName,1),len(ColumnName))
This will work I think:
Declare #String varchar(100)
Set #String = 'okbogkbogkbokgbokgobkgobkofkgbokfgbo&name=fokdofkd&okfaos'
Select SubString(#String,CharIndex('name=',#String),len(#String))
This produces:
'name=fokdofkd&okfaos'