SQL - Replace string function is not working as intended - sql-server

I have a simple string; for example,'01023201580001'.
I would like to replace the last two characters of this string; '01', with '00'.
I could extract the last two characters from this string as RIGHT(columname,2) and then use
REPLACE([columname], RIGHT([columname], 2), '00') as newColumnString
But in the result, it replaces the first two characters as well?
Expected result: 01023201580000
Result I get: 00023201580000
What am I doing wrong?

The second argument to the replace() function defines a pattern to match. The function will look for all instances of that pattern in the target string (first argument) and replace them with the replacement text (third argument).
If you know you only need to change the last two characters, you can take the value excluding those characters and then append the characters you want:
select left(columname, len(columname) - 2) + '00';
If you are doing this for an entire column and some of the rows might not end with '01', you can filter those out:
update MyTable
set columname = left(columname, len(columname) - 2) + '00'
where columname like '%01';
You could also use stuff() in a similar way.

In SQL server, you can use substring like so:
DECLARE #s NVARCHAR(20) = N'01023201580001';
DECLARE #ReplaceWith NVARCHAR(20) = N'00';
SELECT SUBSTRING(#s, 0, LEN(#s) - 1) + #ReplaceWith;
Output: 01023201580000

Related

SQL Server - remove left part of string before a specific character

I have a VARCHAR value that looks like this:
5.95 $ Additional fees
How can I remove everything left from character '$' (including that character) ? So that I get the following result:
Additional fees
The '$' is always present.
STUFF and CHARINDEX would be the simpliest way, in my opinion:
SELECT STUFF(YourColumn,1, CHARINDEX('$',YourColumn),'')
FROM (VALUES('5.95 $ Additional fees'))V(YourColumn);
Note that as $ has a whitespace afterwards, the value returned will have a leading whitespace (' Additional fees'). You could use TRIM (or LTRIM and RTRIM on older versions of SQL Server) to remove this, if it isn't wanted.
I haven't assumed that the portion string to be replaced is CHARINDEX('$',YourColumn)+1, as we have one sample. As far as we know, you could also have values such as '10.99$Base Cost'. If the +1 was used, it would return 'ase Cost' for such a value.
Hello do it like below syntax
declare #temp nvarchar(max)='5.95 $ Additional fees'
select SUBSTRING(#temp,charindex('$',#temp)+1,len(#temp)-1)
You can use SUBSTRING get the particular string and CHARINDEX function to get index of special character, in your case $.
DECLARE #Var VARCHAR(100)
SET #Var = '5.95 $ Additional fees'
SELECT SUBSTRING(#Var, CHARINDEX('$', #Var) + 1, LEN(#Var) - LEN(LEFT(#Var, CHARINDEX('$', #Var))))

Select substring between two words in a long string

I have a table with a large string column called "HL7_MESSAGE" that I need to pull a string from several key words, as you'll see in the code below. I'm an Oracle person so the code was written and works in Oracle SQL but I need to convert it into SQL server code. SQL server doesn't have Regexp_substr function but I haven't been able to get this to work using charindex or Patindex. Basically I select a string between two strings and in the decode statements I look for if there is data missing between the two words/sections. If it just finds '.br\' then it's missing data and I just flag missing or filled. Anyway, code is below...if someone can decode it to SQL server version 2011 I would appreciate it.
CODE:
select
primary_key,
trim(REPLACE(trim(regexp_substr(hl7_message, 'RHRN:(.*)BIRTHDATE:', 1, 1, null, 1)),'\.br\',' ')) AS PATIENT_RHRN,
trim(REPLACE(trim(regexp_substr(hl7_message, 'PATIENT NAME:(.*)RHRN:', 1, 1, null, 1)),'\.br\',' ')) AS PATIENT_NAME,
trim(REPLACE(trim(regexp_substr(hl7_message, 'ULI:(.*)GENDER:', 1, 1, null, 1)),'\.br\',' ')) AS PATIENT_ULI,
decode(replace(to_char(regexp_substr(hl7_message,'FINDINGS:(.*)ADVERSE EVENTS:',1,1,'',1)),'\.br\'),NULL, 'missing', 'filled') FINDINGS_TO_ADVS_EVENTS_FLAG,
decode(replace(to_char(regexp_substr(hl7_message,'IMPRESSIONS:(.*)RECOMMENDATIONS:',1,1,'',1)),'\.br\'),NULL, 'missing', 'filled') IMPRESSION_TO_RECOMM_FLAG,
decode(replace(to_char(regexp_substr(hl7_message,'RECOMMENDATIONS:(.*)_____________________________',1,1,'',1)),'\.br\'),NULL, 'missing', 'filled') RECOMM_TO_SIG_UNDERLINE
from TEST;
Thanks
I have provided below a quick example using patindex and substring to extract information from a string between two other strings, Hopefully this will act as a basis for you to be able to do the conversion.
DECLARE #a varchar(300) = 'this is a long string I will extract data from'
PRINT SUBSTRING(#a, PATINDEX('% long %', #a) + LEN('% long %')-2, PATINDEX('% extract %', #a) - (PATINDEX('% long %', #a) + LEN('% long %')-2))
The key is in using the two patindex patterns to determine the start point and length:
First find the end of the first string pattern (Patindex to find the start, len - 2 for the end):
Patindex(pattern, string) + LEN(pattern, string) - 2
Then to find the length, use Patindex to find the start of the second string, and subtract the start point found above.
Patindex(pattern, string) - (Patindex(start pattern, string) + LEN(start pattern, string) - 2 )
I hope that this helps.

T-SQL 2008: Parse String

I have the following location as a string:
\\Windows\UnitB\CU1234_001\
I want to return the CU1234_001 part only. The query which I need to use needs to be dynamic since this string will change and it could be longer or shorter (it will all the time end in "\".
I've tried to used something like this but this just eliminate the last "\" and returns the rest of the string:
select
substring('\\Windows\UnitB\CU1234_001\',
1, (len('\\Windows\UnitB\CU1234_001\') - (Charindex('\',
reverse(rtrim('\\Windows\UnitB\CU1234_001\'))))))
You can use a combination of string functions to extract what you want:
SELECT REVERSE(SUBSTRING(REVERSE(col),
2,
CHARINDEX('/', REVERSE(col), 2) - 2))
FROM yourTable

SQL: Fix for CSV import mistake

I have a database that has multiple columns populated with various numeric fields. While trying to populate from a CSV, I must have mucked up assigning delimited fields. The end result is a column containing It's Correct information, but also contains the next column over's data- seperated by a comma.
So instead of Column UPC1 containing "958634", it contains "958634,95877456". The "95877456" is supposed to be in the UPC2 column, instead UPC2 is NULL.
Is there a way for me to split on the comma and send the data to UPC2 while keeping UPC1 data before the comma in tact?
Thanks.
You can do this with string functions. To query the values and verify the logic, try this:
SELECT
LEFT(UPC1, CHARINDEX(',', UPC1) - 1),
SUBSTRING(UPC1, CHARINDEX(',', UPC1) + 1, 1000)
FROM myTable;
If the result is what you want, turn it into an update:
UPDATE myTable SET
UPC1 = LEFT(UPC1, CHARINDEX(',', UPC1) - 1),
UPC2 = SUBSTRING(UPC1, CHARINDEX(',', UPC1) + 1, 1000);
The expression for UPC1 takes the left side of UPC1 up to one character before the comma.
The expression for UPC2 takes the remainder of the UPC1 string starting one character after the comma.
The third argument to SUBSTRING needs some explaining. It's the number of characters you want to include after the starting position of the string (which in this case is one character after the comma's location). If you specify a value that's longer than the string SUBSTRING will just return to the end of the string. Using 1000 here is a lot easier than calculating the exact number of characters you need to get to the end.

Sql Server's regex LIKE - behaviour clarification?

Someone asked here how to get only values which are a number :
So , if the table is :
DECLARE #Table TABLE(
Col nVARCHAR(50)
)
INSERT INTO #Table SELECT 'ABC'
INSERT INTO #Table SELECT '234.62'
INSERT INTO #Table SELECT '10:10:10:10'
INSERT INTO #Table SELECT 'France'
INSERT INTO #Table SELECT '2'
then - the desired results are :
234.62
2
But when I tested this query :
SELECT * FROM #Table WHERE Col LIKE '%[0-9.]%' --expected to see only 234.62
it showed :
234.62
10:10:10:10
2
Question #1
How come 10:10:10:10 , 2 satisfies the condition ?
Question #2
I saw this answer here which does work
SELECT * FROM #Table WHERE Col NOT LIKE '%[^0-9.]%'
But I don't understand why this works. AFAIU - it selects all values which are not like (not(has number) and not( has dot)) which is ===>(de morgan)===> not like ( has number or has dot)
Can someone please shed light ?
nb I already know that isnumeric can be used also , but it's unsafe (+). also valid wildcards are %,_,[],[^]
Any particular use of [set] within a LIKE expression is a check against one character in the target string.
So, LIKE '%[0-9.]%' says - % - match 0-to-many arbitrary characters, then [0-9.] match one character in the set 0-9., and then % match 0-to-many arbitrary characters. Paraphrased, it says "match any string that contains at least one character in the set 0-9.". So, 10:10:10:10 can be matched as 0 arbitrary characters, then 1 matches [0-9.], and then 0:10:10:10 matches the final %.
LIKE '%[^0-9.]%' says - % - match 0-to-many arbitrary characters, then [^0-9.] match one character not in the set 0-9., and then % match 0-to-many arbitrary characters. Paraphrased, it says "match any string that contains at least one character outside of the set 0-9.. So when we apply the NOT to the front of that, we are saying "match any string that doesn't contain at least one character outside of the set 0-9." or "match strings that only contain characters in the set 0-9..
Essentially, the double-negative is a way to make an assertion about all characters in the string.

Resources