Reputation: 1
I tried a query to get the below result from a string. But its not showing the accurate result.
String: ty-R
Desired Output: ty
String: tuy-R
Desired Output: tuy
I tried using replace function. But I am unable to remove the next hyphen as I have to use the first one.
DECLARE @str NVARCHAR(MAX);
DECLARE @lpcounter INT;
SET @str = 'ty-R ';
SET @lpcounter = 0;
WHILE @lpcounter <= 26
BEGIN
SET @str = REPLACE(@str, CHAR(65 + @lpcounter), '');
SET @lpcounter = @lpcounter + 1;
END;
SELECT @str;
Can this be done through a query only?
Upvotes: 0
Views: 3863
Reputation: 7918
I like @Sami's TRANSLATE Solution which, if I were on SQL Server 2017+, I would likely use. Another efficient option would be to use PatExclude8K (DDL included below).
-- Sample Data
DECLARE @table TABLE (string VARCHAR(1000));
INSERT @table VALUES ('8-R1-WEL'),('276-R1E')
-- Solution
SELECT
OldString = t.string,
NewString = IIF(f.NewString LIKE '%-',SUBSTRING(f.NewString,0,LEN(f.NewString)),f.NewString)
FROM @table AS t
CROSS APPLY dbo.PatExclude8K(t.string,'[^0-9-]') AS f;
Results:
OldString NewString
------------ -------------
8-R1-WEL 8-1
276-R1E 276-1
PatExclude8K code:
CREATE FUNCTION dbo.PatExclude8K
(
@String VARCHAR(8000),
@Pattern VARCHAR(50)
)
/*******************************************************************************
Purpose:
Given a string (@String) and a pattern (@Pattern) of characters to remove,
remove the patterned characters from the string.
Usage:
--===== Basic Syntax Example
SELECT CleanedString
FROM dbo.PatExclude8K(@String,@Pattern);
--===== Remove all but Alpha characters
SELECT CleanedString
FROM dbo.SomeTable st
CROSS APPLY dbo.PatExclude8K(st.SomeString,'%[^A-Za-z]%');
--===== Remove all but Numeric digits
SELECT CleanedString
FROM dbo.SomeTable st
CROSS APPLY dbo.PatExclude8K(st.SomeString,'%[^0-9]%');
Programmer Notes:
1. @Pattern is not case sensitive (the function can be easily modified to make it so)
2. There is no need to include the "%" before and/or after your pattern since since we
are evaluating each character individually
Revision History:
Rev 00 - 10/27/2014 Initial Development - Alan Burstein
Rev 01 - 10/29/2014 Mar 2007 - Alan Burstein
- Redesigned based on the dbo.STRIP_NUM_EE by Eirikur Eiriksson
(see: http://www.sqlservercentral.com/Forums/Topic1585850-391-2.aspx)
- change how the cte tally table is created
- put the include/exclude logic in a CASE statement instead of a WHERE clause
- Added Latin1_General_BIN Colation
- Add code to use the pattern as a parameter.
Rev 02 - 11/6/2014
- Added final performane enhancement (more cudo's to Eirikur Eiriksson)
- Put 0 = PATINDEX filter logic into the WHERE clause
Rev 03 - 5/16/2015
- Updated code to deal with special XML characters
*******************************************************************************/
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH
E1(N) AS (SELECT N FROM (VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) AS X(N)),
itally(N) AS
(
SELECT TOP(CONVERT(INT,LEN(@String),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM E1 T1 CROSS JOIN E1 T2 CROSS JOIN E1 T3 CROSS JOIN E1 T4
)
SELECT NewString =
((
SELECT SUBSTRING(@String,N,1)
FROM iTally
WHERE 0 = PATINDEX(@Pattern,SUBSTRING(@String COLLATE Latin1_General_BIN,N,1))
FOR XML PATH(''),TYPE
).value('(text())[1]','varchar(8000)'));
GO
Upvotes: 0
Reputation: 14928
Here you go
WITH C AS
(
SELECT REPLACE(
TRANSLATE(V, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', REPLICATE(' ', 26) --Or SPACE(26)
)
, ' ', '') Res
FROM
(
VALUES
('8-R1-WEL'),
('276-R1E')
) T(V)
)
SELECT CASE WHEN RIGHT(Res, 1) = '-'
THEN LEFT(Res, LEN(Res) -1)
ELSE Res
END Result
FROM C;
Finally, I would recommend doing string manipulation using a other programming language instead of doing it in the database.
Upvotes: 2
Reputation: 960
Here is one method using patindex to find alpha characters in the string, iterate over that string and then use the length of the string to form a loop to remove these.
DECLARE @str NVARCHAR(MAX);
DECLARE @replacestring nvarchar(max);
declare @stop int = 0;
SET @str = '276-R1E';
select @stop=len(@str);
while @stop>0
begin
select @replacestring = substring(@Str, patindex('%[a-z]%', @str), 1);
select @str = replace(@str,@replacestring, '');
select @stop-=1;
end
SELECT @str;
Upvotes: 0
Reputation: 1269873
This returns the values that you specify in the question:
select str, replace(left(str, charindex('-', str) + 2), 'R', '')
from (values ('8-R1-WEL'), ('276-R1E')) v(str);
You haven't expressed the logic, so this does the following:
Upvotes: 0