Remove characters between ~~ sql - sql

My data is showing as "abcdefghijklmno~123~pqrstuvwzyz"
I want to remove this part ~123~
I want to get data as "abcdefghijklmnopqrstuvwzyz" after remove this part ~123~

You could use substring operations here:
SELECT
col,
SUBSTRING(col, 1, CHARINDEX('~', col) - 1) +
SUBSTRING(col, CHARINDEX('~', col, CHARINDEX('~', col) + 1) + 1, LEN(col)) AS output
FROM yourTable;
Data:
WITH yourTable AS (
SELECT 'abcdefghijklmno~123~pqrstuvwzyz' AS col
)
Demo

Related

Substring, Charindex

I'm trying to extract a code that varies in length that exists after the first two underscores and before the third underscore in a field in a table. The table looks something like this. There are greater than 30 codes and I need to extract the code as part of a query.
code
====
XX_YYY_CODE1_ZZZ
XX_YYY_CODE2_ZZZ
XX_YYY_CODE3_ZZZ
XX_YYY_CODE4_ZZZ
...
I've tried using this code however this gives me YYY rather than the CODE I'm after and I can't work out how to re-engineer it to do what I want it to do.
select
left(SUBSTRING(code,
CHARINDEX('_', code) + 1, len(code)),
CHARINDEX('_',SUBSTRING(code,CHARINDEX('_', code) + 2, LEN(code))))
if only four underscore,Use below code
select parsename(replace('1_2_3_4','_','.'),2)
Try this expression instead:
SELECT SUBSTRING
(code,
CHARINDEX('_', code, CHARINDEX('_', code) + 1) + 1,
LEN(code) -
(CHARINDEX('_', code, CHARINDEX('_', code) + 1) + 1) -
CHARINDEX('_',REVERSE(code))
)
Use below code,I hope it is give your expected result :
CREATE TABLE #Table(GvnString VARCHAR(100))
INSERT INTO #Table( GvnString )
SELECT 'XX_YYY_Code1_ZZZ' UNION ALL
SELECT 'XX_YYY_Code2_ZZZ' UNION ALL
SELECT 'XX_YYY_Code3_ZZZ' UNION ALL
SELECT 'XX_YYY_Code4_ZZZ'
SELECT SUBSTRING(GvnString, CHARINDEX('_', GvnString, CHARINDEX('_',
GvnString) + 1) + 1, LEN(GvnString) - CHARINDEX('_', GvnString,
CHARINDEX('_', GvnString) + 1))
FROM #Table
I am reversing the string and doing the substring operation.
CREATE TABLE #MyTable(Code VARCHAR(50))
INSERT INTO #MyTable( Code)
SELECT 'XX_YYY_Code1_ZZZ' UNION ALL
SELECT 'XX_YYY_Code2_ZZZ' UNION ALL
SELECT 'XX_YYY_Code3_ZZZ' UNION ALL
SELECT 'XX_YYY_Code4_ZZZ'
select Reverse(Substring
(substring (Reverse(code),charindex('_',Reverse(code))+1,Len(code)),0,
CHARINDEX('_',substring (Reverse(code),charindex('_',Reverse(code))+1,Len(code)))))
from #Table
Just modified your code. It should work.
select
SUBSTRING(
substring(substring(code,CHARINDEX('_', code)+1,len(code))
,CHARINDEX('_', substring(code
,CHARINDEX('_', code)+1,len(code)))+1
,len(code)),1,
LEN(substring(substring(code,CHARINDEX('_', code)+1,len(code))
,CHARINDEX('_', substring(code
,CHARINDEX('_', code)+1,len(code)))+1
,len(code)))
- len(substring(substring(substring(code,CHARINDEX('_', code)+1,len(code))
,CHARINDEX('_', substring(code
,CHARINDEX('_', code)+1,len(code)))+1
,len(code)),CHARINDEX('_', substring(substring(code,CHARINDEX('_', code)+1,len(code))
,CHARINDEX('_', substring(code
,CHARINDEX('_', code)+1,len(code)))+1
,len(code)))+1,
LEN(substring(substring(code,CHARINDEX('_', code)+1,len(code))
,CHARINDEX('_', substring(code
,CHARINDEX('_', code)+1,len(code)))+1
,len(code)))))-1)
A slightly modified answer from dotNET does what I needed. Examples below;
SELECT SUBSTRING
('XX_YYY_LongCode_ZZZ',
CHARINDEX('_', 'XX_YYY_LongCode_ZZZ', CHARINDEX
('_', 'XX_YYY_LongCode_ZZZ') + 1) + 1,
LEN('XX_YYY_LongCode_ZZZ') -
(CHARINDEX('_', 'XX_YYY_LongCode_ZZZ', CHARINDEX
('_', 'XX_YYY_LongCode_ZZZ') + 1)) -
CHARINDEX('_',REVERSE('XX_YYY_LongCode_ZZZ'))
)
Or another example
SELECT SUBSTRING
('XX_YYY_otherCode_ZZZ',
CHARINDEX('_', 'XX_YYY_otherCode_ZZZ', CHARINDEX
('_', 'XX_YYY_otherCode_ZZZ') + 1) + 1,
LEN('XX_YYY_otherCode_ZZZ') -
(CHARINDEX('_', 'XX_YYY_otherCode_ZZZ', CHARINDEX
('_', 'XX_YYY_otherCode_ZZZ') + 1)) -
CHARINDEX('_',REVERSE('XX_YYY_otherCode_ZZZ'))
)

Remove text after multiple specific characters

I have to combine two text columns, and then remove all text after a /, or (, or the word "with"
Example:
The combine of the two columns looks like this:
Select ,COALESCE(DT.Column1, '') + ' ' + COALESCE(M.Column2, '') AS Result1
from Table1 dt
join Table2 M on dt.M_Id =M.id
Result set looks like this currently:
SomeResults/Here
SomeMoreResults(here)
AndMoreResultsWITHthis
I need them to look like this:
SomeResults
SomeMoreResults
AndMoreResults
Using SUBSTRING function:
SELECT CASE
WHEN Col LIKE '%/%' THEN SUBSTRING(Col, 1, CHARINDEX('/', Col)-1)
WHEN Col LIKE '%(%' THEN SUBSTRING(Col, 1, CHARINDEX('(', Col)-1)
WHEN Col LIKE '%WITH%' THEN SUBSTRING(Col, 1, CHARINDEX('WITH', Col)-1)
END;
You can use left():
select (case when col like '%/%' and col not like '%WITH%/%'
then left(col, charindex('%/%', col)) - 1
when col like '%WITH%'
then left(col, charindex('%WITH%', col)) - 1
else col
end) as newcol
Note: If caps are important for 'WITH', you might need to fiddle with collations as well.

Pad Zero before first hypen and remove spaces and add BA and IN

I have data as below
98-45.3A-22
104-44.0A-23
00983-29.1-22
01757-42.5A-22
04968-37.3A2-23
Output Looking for output as below in SQL Server
00098-BA45.3A-IN-22
00104-BA44.0A-IN-23
00983-BA29.1-IN-22
01757-BA42.5A-IN-22
04968-BA37.3A2-IN-23
I splitted parts to cope with tricky data templates. This should work even with non-dash-2-digit tail:
WITH Src AS
(
SELECT * FROM (VALUES
('98-45.3A-22'),
('104-44.0A-23'),
('00983-29.1-22'),
('01757-42.5A-22'),
('04968-37.3A2-23')
) T(X)
), Parts AS
(
SELECT *,
RIGHT('00000'+SUBSTRING(X, 1, CHARINDEX('-',X, 1)-1),5) Front,
'BA'+SUBSTRING(X, CHARINDEX('-',X, 1)+1, 2) BA,
SUBSTRING(X, PATINDEX('%.%',X), LEN(X)-CHARINDEX('-', REVERSE(X), 1)-PATINDEX('%.%',X)+1) P,
SUBSTRING(X, LEN(X)-CHARINDEX('-', REVERSE(X), 1)+1, LEN(X)) En
FROM Src
)
SELECT Front+'-'+BA+P+'-IN'+En
FROM Parts
It returns:
00098-BA45.3A-IN-22
00104-BA44.0A-IN-23
00983-BA29.1-IN-22
01757-BA42.5A-IN-22
04968-BA37.3A2-IN-23
Try this,
DECLARE #String VARCHAR(100) = '98-45.3A-22'
SELECT ISNULL(REPLICATE('0',6 - CHARINDEX('-',#String)),'') -- Add leading Zeros
+ STUFF(
STUFF(#String,CHARINDEX('-',#String),1,'-BA'), -- Add 'BA'
CHARINDEX('-',#String,CHARINDEX('-',#String)+1)+2, -- 2 additional for the character 'BA'
1,'-IN') -- Add 'IN'
What if I have more than 6 digit number before first hyphen and want to remove the leading zeros to make it 6 digits.
DECLARE #String VARCHAR(100) = '0000098-45.3A-22'
SELECT CASE WHEN CHARINDEX('-',#String) <= 6
THEN ISNULL(REPLICATE('0',6 - CHARINDEX('-',#String)),'') -- Add leading Zeros
+ STUFF(
STUFF( #String,CHARINDEX('-',#String),1,'-BA'), -- Add 'BA'
CHARINDEX('-',#String,CHARINDEX('-',#String)+1)+2, -- 2 additional for the character 'BA'
1,'-IN') -- Add 'IN'
ELSE STUFF(
STUFF(
STUFF(#String,CHARINDEX('-',#String),1,'-BA'), -- Add 'BA'
CHARINDEX('-',#String,CHARINDEX('-',#String)+1)+2, -- 2 additional for the character 'BA'
1,'-IN'), -- Add 'IN'
1, CHARINDEX('-',#String) - 6, '' -- remove extra leading Zeros
)
END
Making assumptions that the format is consistent (e.g. always ends with "-" + 2 characters....)
DECLARE #Data TABLE (Col1 VARCHAR(100))
INSERT #Data ( Col1 )
SELECT Col1
FROM (
VALUES ('98-45.3A-22'), ('104-44.0A-23'),
('00983-29.1-22'), ('01757-42.5A-22'),
('04968-37.3A2-23')
) x (Col1)
SELECT RIGHT('0000' + LEFT(Col1, CHARINDEX('-', Col1) - 1), 5)
+ '-BA' + SUBSTRING(Col1, CHARINDEX('-', Col1) + 1, CHARINDEX('.', Col1) - CHARINDEX('-', Col1))
+ SUBSTRING(Col1, CHARINDEX('.', Col1) + 1, LEN(Col1) - CHARINDEX('.', Col1) - 3)
+ '-IN-' + RIGHT(Col1, 2)
FROM #Data
It's not ideal IMO to do this string manipulation all the time in SQL. You could shift it out to your presentation layer, or store the pre-formatted value in the db to save the cost of this every time.
Use REPLICATE AND CHARINDEX:
Replicate: will repeat given character till reach required count specify in function
CharIndex: Finds the first occurrence of any character
Declare #Data AS VARCHAR(50)='98-45.3A-22'
SELECT REPLICATE('0',6-CHARINDEX('-',#Data)) + #Data
SELECT
SUBSTRING
(
(REPLICATE('0',6-CHARINDEX('-',#Data)) +#Data)
,0
,6
)
+'-'+'BA'+ CAST('<x>' + REPLACE(#Data,'-','</x><x>') + '</x>' AS XML).value('/x[2]','varchar(max)')
+'-'+ 'IN'+ '-' + CAST('<x>' + REPLACE(#Data,'-','</x><x>') + '</x>' AS XML).value('/x[3]','varchar(max)')
In another way by using PARSENAME() you can use this query:
WITH t AS (
SELECT
PARSENAME(REPLACE(REPLACE(s, '.', '###'), '-', '.'), 3) AS p1,
REPLACE(PARSENAME(REPLACE(REPLACE(s, '.', '###'), '-', '.'), 2), '###', '.') AS p2,
PARSENAME(REPLACE(REPLACE(s, '.', '###'), '-', '.'), 1) AS p3
FROM yourTable)
SELECT RIGHT('00000' + p1, 5) + '-BA' + p2 + '-IN-' + p3
FROM t;

SQL-Server: Replace except first and last characters

Is there any ways to SELECT the first and last 2 characters and REPLACE all the other characters with * as shown below?
WA***RT
EX*** ***IL
CH***ON
BE******* *****AY
AP*LE
Thanks in advance!
Spaces skipped:
SELECT
name,
[hidden] = CASE WHEN LEN(name) <= 4 THEN name
ELSE CONCAT(LEFT(name, 2),REPLICATE('*', LEN(name)- 2),RIGHT(name,2))
END
FROM #tab;
If you need spaces and there is only one you can use:
SELECT name,
[hidden] = CASE
WHEN LEN(name) <= 4 THEN name
WHEN CHARINDEX(' ', name) > 0
THEN STUFF(CONCAT(LEFT(name, 2),REPLICATE('*', LEN(name) - 2) ,
RIGHT(name,2)), CHARINDEX(' ', name),1, ' ')
ELSE CONCAT(LEFT(name, 2),REPLICATE('*', LEN(name) - 2) ,RIGHT(name,2))
END
FROM #tab;
LiveDemo
If you use version lower than SQL Server 2012 concatenate string with +.
select left(col, 2) + REPLICATE('*',len(col)-4) + right(col,2) from table;
You can use STUFF.
SELECT STUFF(col, 3, LEN(col)-4, REPLICATE('*',LEN(col)-4))
This doesn't preserve spaces.
To preserve N spaces, you can simply "add back spaces" with STUFF again:
SELECT col,
masked =
coalesce(
-- handle 2 spaces
STUFF(STUFF(
STUFF(col, 3, LEN(col)-4, REPLICATE('*',LEN(col)-4)),
CHARINDEX(' ', col), 1, ' '),
CHARINDEX(' ', col, CHARINDEX(' ', col)+1), 1, ' '),
-- handle 1 spaces
STUFF(
STUFF(col, 3, LEN(col)-4, REPLICATE('*',LEN(col)-4)),
CHARINDEX(' ', col), 1, ' '),
-- normal masking
STUFF(col, 3, LEN(col)-4, REPLICATE('*',LEN(col)-4)),
-- too short to mask
col
)
Demo

Extract string between after second / and before -

I have a field that holds an account code. I've managed to extract the first 2 parts OK but I'm struggling with the last 2.
The field data is as follows:
812330/50110/0-0
812330/50110/BDG001-0
812330/50110/0-X001
I need to get the string between the second "/" and the "-" and after the "-" .Both fields have variable lengths, so I would be looking to output 0 and 0 on the first record, BDG001 and 0 on the second record and 0 and X001 on the third record.
Any help much appreciated, thanks.
You can use CHARINDEX and LEFT/RIGHT:
CREATE TABLE #tab(col VARCHAR(1000));
INSERT INTO #tab VALUES ('812330/50110/0-0'),('812330/50110/BDG001-0'),
('812330/50110/0-X001');
WITH cte AS
(
SELECT
col,
r = RIGHT(col, CHARINDEX('/', REVERSE(col))-1)
FROM #tab
)
SELECT col,
r,
sub1 = LEFT(r, CHARINDEX('-', r)-1),
sub2 = RIGHT(r, LEN(r) - CHARINDEX('-', r))
FROM cte;
LiveDemo
EDIT:
or even simpler:
SELECT
col
,sub1 = SUBSTRING(col,
LEN(col) - CHARINDEX('/', REVERSE(col)) + 2,
CHARINDEX('/', REVERSE(col)) -CHARINDEX('-', REVERSE(col))-1)
,sub2 = RIGHT(col, CHARINDEX('-', REVERSE(col))-1)
FROM #tab;
LiveDemo2
EDIT 2:
Using PARSENAME SQL SERVER 2012+ (if your data does not contain .):
SELECT
col,
sub1 = PARSENAME(REPLACE(REPLACE(col, '/', '.'), '-', '.'), 2),
sub2 = PARSENAME(REPLACE(REPLACE(col, '/', '.'), '-', '.'), 1)
FROM #tab;
LiveDemo3
...Or you can do this, so you only go from left side to right, so you don't need to count from the end in case you have more '/' or '-' signs:
SELECT
SUBSTRING(columnName, CHARINDEX('/' , columnName, CHARINDEX('/' , columnName) + 1) + 1,
CHARINDEX('-', columnName) - CHARINDEX('/' , columnName, CHARINDEX('/' , columnName) + 1) - 1) AS FirstPart,
SUBSTRING(columnName, CHARINDEX('-' , columnName) + 1, LEN(columnName)) AS LastPart
FROM table_name
One method way is to download a split() function off the web and use it. However, the values end up in separate rows, not separate columns. An alternative is a series of nested subqueries, CTEs, or outer applies:
select t.*, p1.part1, p12.part2, p12.part3
from table t outer apply
(select t.*,
left(t.field, charindex('/', t.field)) as part1,
substring(t.field, charindex('/', t.field) + 1) as rest1
) p1 outer apply
(select left(p1.rest1, charindex('/', p1.rest1) as part2,
substring(p1.rest1, charindex('/', p1.rest1) + 1, len(p1.rest1)) as part3
) p12
where t.field like '%/%/%';
The where clause guarantees that the field value is in the right format. Otherwise, you need to start sprinkling the code with case statements to handle misformated data.