I want to remove part of string from a string - sql

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

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

Get everything before a certain character in SQL

I got the following entries in my database:
E01234-1-1
E01234444-1-800000000
I want to trim the entry so I get:
E01234-1
E01234444-1
So basically, I want everything before the second '-' regardless of the length
How can I solve it? Im using MS SQL SERVER 2012
I am using this but it only bring data from before first hyphen, not second hyphen
DECLARE #TABLE TABLE (STRING VARCHAR(100))
INSERT INTO #TABLE (STRING)
SELECT 'E01234-1-1'
UNION ALL SELECT 'E01234-1-200'
UNION ALL SELECT 'E01234-1-3000'
UNION ALL SELECT 'E01234-1-40000'
UNION ALL SELECT 'E01234-1-500000'
UNION ALL SELECT 'E01234-1-6000000'
UNION ALL SELECT 'E01234-1-70000000'
UNION ALL SELECT 'E01234444-1-800000000'
SELECT LEFT(STRING, CHARINDEX('-',STRING)-1) STRIPPED_STRING from #TABLE
RETURNS
E01234
E01234
E01234
E01234
E01234
E01234
E01234
E01234444
If you need the second -:
SELECT
LEFT(STRING, CHARINDEX('-', #test, CHARINDEX('-', #test) + 1) -1) STRIPPED_STRING
FROM #TABLE
Explanation: CHARINDEX will get you the index of the - - doing it twice (+ 1) specifies that the outter CHARINDEX should start at the spot after the first - in the string.
If you want to chop off everything after the last - instead (regardless of whether it's second or not):
SELECT
LEFT(STRING, LEN(STRING) - CHARINDEX('-', REVERSE(STRING))) STRIPPED_STRING
FROM #table
This time, you get the CHARINDEX of the last (reverse the string) -, and subtract that from the length of the whole string.
Try this:
DECLARE #STR NVARCHAR(MAX) = 'E01234444-1-800000000';
SELECT LEFT(#STR, CHARINDEX('-', #STR, CHARINDEX('-', #STR)) - 1)
If you are using MySQL use something like this:
SELECT SUBSTRING_INDEX(fieldname, '-', 2) FROM tablename

Split string and take last element

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

Truncating Strings from a column name

I have a column which has values divided by colon ":".
For example DT:CSDF , SFT:TAHS etc...
I just need to take the right side i.e. CSDF,TAHS etc
How do I do it in the select clause?
If you will never have dots, you can use this
PARSENAME(REPLACE(ColumnName,':','.'),1)
example
DECLARE #v VARCHAR(100) = 'DT:CSDF'
SELECT PARSENAME(REPLACE(#v,':','.'),1)
otherwise use PATINDEX and RIGHT
SELECT RIGHT(ColumnName,LEN(ColumnName) -PATINDEX('%:%',ColumnName))
Example
DECLARE #v VARCHAR(100) = 'DT:CSDF'
SELECT RIGHT(#v,LEN(#v) -PATINDEX('%:%',#v))
Like this:
SELECT SUBSTRING(YourField,
CHARINDEX(':', YourField) + 1,
LEN(YourField)
) AS YourNewField
something like this:
SUBSTR( INSTR( mycol, ':' ) )
SELECT SUBSTRING(fieldname, CHARINDEX(':', fieldname) + 1, LEN(fieldname))
FROM ...
More t-sql string functions you can find here:
http://msdn.microsoft.com/en-US/library/ms181984(v=sql.90).aspx

how to convert string format

How can I convert a number to a formatted string of fixed length in SQL Server 2005 using T-SQL?
e.g.
Inputs: 5,01,007,0009,00011,01200
Result: 000005,000007,000009,0000011,001200
Looks like you want it 6 wide. Try putting your pad characters, in this case, zeros, to the left of your int/string, and then take the 6 chars on the right side of the string.
How about this?
DECLARE #i int;
SELECT #i = 1200;
SELECT RIGHT('000000'+ CAST(#i as varchar(10)), 6);
The best way I've found to do this is using the STR statement:
SELECT REPLACE(STR(123, 6), ' ', '0')
The above statement will result in 000123. It basically converts 123 to a string of 6 characters (padded with spaces), then uses REPLACE to replace the spaces with zeros.
TRY THIS
WITH t(c) AS
(
SELECT 1.99 UNION ALL
SELECT 21.34 UNION ALL
SELECT 1797.94 UNION ALL
SELECT 300.36 UNION ALL
SELECT 21.99 UNION ALL
SELECT -2.31
)
select
c,
replicate(0,4-len(replace(substring(cast(c as varchar(10)),1,charindex('.',c)-1),'-','')))+''+
replace(replace(substring(cast(c as varchar(10)),1,charindex('.',c)-1),'-',''),'','-') +''+
replace(substring(cast(c as varchar(10)),charindex('.',c),len(c)),'-','')
from t
i will still optimize it
Best way for dynamic leading zero allocation
WITH t(c) AS ( SELECT 1.99 UNION ALL
SELECT 21.34 UNION ALL SELECT
1797.94 UNION ALL SELECT 300.36 UNION ALL SELECT 21.99 UNION ALL
SELECT 2.31 ),
Final (a,b,c,d) as ( Select c,
substring(cast(c as
varchar(10)),1,charindex('.',c)-1) ,
(select max(len(substring(cast(c as
varchar(10)),1,charindex('.',c)-1)))
from t), substring(cast(c as
varchar(10)),charindex('.',c)+1,len(c))
From t group by c )
select a,
right(replicate('0',c)+''+b,4)+'.'+d
from final
declare #i int
set #i=10
print replace(str(#i),' ','0')