Queennie L
asked on
Replace Leading Zeros after the first 3 letters in a value with spaces
Hello Experts,
I have a query that I want to replace leading zeros after the first 3 Letters of a value in SQL query. Please see attached.
Is this possible?
This is the query I have I come up with below:
Thank you again for all your help.
ReplaceLeadingZero_To_Space.xlsx
I have a query that I want to replace leading zeros after the first 3 Letters of a value in SQL query. Please see attached.
Is this possible?
This is the query I have I come up with below:
REPLACE(LEFT([ClaimNo],5),'0',' ')+RIGHT([ClaimNo],9)
Thank you again for all your help.
ReplaceLeadingZero_To_Space.xlsx
No this cannot work with the three introductory letters.
Use following formula to remove leading zeros from the 9 digits long number following three letters:
Following query will replace leading zeros by spaces:
Use following formula to remove leading zeros from the 9 digits long number following three letters:
SELECT LEFT(ClaimNo, 3) + CAST(CAST(RIGHT(ClaimNo, 9) AS int) AS varchar(9))
Following query will replace leading zeros by spaces:
SELECT LEFT(ClaimNo, 3) + RIGHT(SPACE(9)+CAST(CAST(RIGHT(ClaimNo, 9) AS int) AS varchar(9)), 9)
select replace(claim_no, '0',' ') from table
I'm not sure what you mean by leading zeroes after the first three letters. If claim_no always starts with three letters, then the above should work.
I'm not sure what you mean by leading zeroes after the first three letters. If claim_no always starts with three letters, then the above should work.
Oops, I jut figured out what you meant, forget the above comment.
I think pcelba is on the right track, although I believe the second cast should be as char(9).
No, the char(9) does not work because it leaves trailing blanks on the output and successive RIGHT then provides incorrect result
ASKER
@pcelba:
I have an error "Conversion failed when converting the nvarchar value '' to data type int."
Thank you again.
I have an error "Conversion failed when converting the nvarchar value '' to data type int."
Thank you again.
Are there always 12 characters in the ClaimNo?
What is the claim_no value which reports the conversion error?
The PATINDEX('%0[1-9]%',@Col0) could also be used and it is very interesting approach but the CAST will do the same work if the claim_no format is XXXNNNNNNNNN.
The PATINDEX('%0[1-9]%',@Col0)
ASKER
@Norie:
Yes.
Yes.
ASKER
@pcelba:
It will create an Error if ClaimNo value is AAA0. How to work around on this?
Thank you.
It will create an Error if ClaimNo value is AAA0. How to work around on this?
Thank you.
ASKER
What I mean is value is equal to AAA000000000.
If ClaimNo shorther than 12 characters is allowed then you would need one more CAST:
SELECT LEFT(ClaimNo, 3) + RIGHT(SPACE(9)+CAST(CAST(RIGHT(CAST(ClaimNo AS char(12)), 9) AS int) AS varchar(9)), 9)
A couple of questions for clarification:
- Are you wanting to replace the leading zeroes with spaces, or remove leading zeroes? In other words, should ABC00000123 become ABC123 or ABC 123?
- Are the nine characters after the three letters ALWAYS numeric?
General query structure:
SELECT ClaimNo,
CASE WHEN ClaimNoZeroCount = 0 THEN ClaimNo ELSE STUFF(ClaimNo, ClaimNoFirstDigit,
ClaimNoZeroCount, REPLICATE(SPACE(1), ClaimNoZeroCount)) END AS ClaimNoModified
FROM dbo.TableName
CROSS APPLY (
SELECT PATINDEX('%[0-9]%', ClaimNo) AS ClaimNoFirstDigit
) AS ca1
CROSS APPLY (
SELECT CASE WHEN SUBSTRING(ClaimNo, ClaimNoFirstDigit, 1) <> '0' THEN 0
ELSE PATINDEX('%[^0]%', SUBSTRING(ClaimNo, ClaimNoFirstDigit + 1, 1000)) END AS ClaimNoZeroCount
) AS ca2
With sample data:
IF OBJECT_ID('tempdb.dbo.#Tes tData') IS NOT NULL
DROP TABLE #TestData
CREATE TABLE #TestData ( ClaimNo varchar(100) NULL )
INSERT INTO #TestData VALUES('AAA002138961'),('B BB00000356 7'),('CCC0 00052093') ,
('DDD040667709'),('EEE0000 00002'),(' FFF5099100 20'),('JJJ 000297327' ),('MMM992 231023'),
/* just to show the logic is able to handle any format */
('Unexpected00001Format'), ('Unex0000 0Format'), ('Un000000 000234ABC' )
SELECT ClaimNo,
CASE WHEN ClaimNoZeroCount = 0 THEN ClaimNo ELSE STUFF(ClaimNo, ClaimNoFirstDigit,
ClaimNoZeroCount, REPLICATE(SPACE(1), ClaimNoZeroCount)) END AS ClaimNoModified
FROM #TestData
CROSS APPLY (
SELECT PATINDEX('%[0-9]%', ClaimNo) AS ClaimNoFirstDigit
) AS ca1
CROSS APPLY (
SELECT CASE WHEN SUBSTRING(ClaimNo, ClaimNoFirstDigit, 1) <> '0' THEN 0
ELSE PATINDEX('%[^0]%', SUBSTRING(ClaimNo, ClaimNoFirstDigit + 1, 1000)) END AS ClaimNoZeroCount
) AS ca2
SELECT ClaimNo,
CASE WHEN ClaimNoZeroCount = 0 THEN ClaimNo ELSE STUFF(ClaimNo, ClaimNoFirstDigit,
ClaimNoZeroCount, REPLICATE(SPACE(1), ClaimNoZeroCount)) END AS ClaimNoModified
FROM dbo.TableName
CROSS APPLY (
SELECT PATINDEX('%[0-9]%', ClaimNo) AS ClaimNoFirstDigit
) AS ca1
CROSS APPLY (
SELECT CASE WHEN SUBSTRING(ClaimNo, ClaimNoFirstDigit, 1) <> '0' THEN 0
ELSE PATINDEX('%[^0]%', SUBSTRING(ClaimNo, ClaimNoFirstDigit + 1, 1000)) END AS ClaimNoZeroCount
) AS ca2
With sample data:
IF OBJECT_ID('tempdb.dbo.#Tes
DROP TABLE #TestData
CREATE TABLE #TestData ( ClaimNo varchar(100) NULL )
INSERT INTO #TestData VALUES('AAA002138961'),('B
('DDD040667709'),('EEE0000
/* just to show the logic is able to handle any format */
('Unexpected00001Format'),
SELECT ClaimNo,
CASE WHEN ClaimNoZeroCount = 0 THEN ClaimNo ELSE STUFF(ClaimNo, ClaimNoFirstDigit,
ClaimNoZeroCount, REPLICATE(SPACE(1), ClaimNoZeroCount)) END AS ClaimNoModified
FROM #TestData
CROSS APPLY (
SELECT PATINDEX('%[0-9]%', ClaimNo) AS ClaimNoFirstDigit
) AS ca1
CROSS APPLY (
SELECT CASE WHEN SUBSTRING(ClaimNo, ClaimNoFirstDigit, 1) <> '0' THEN 0
ELSE PATINDEX('%[^0]%', SUBSTRING(ClaimNo, ClaimNoFirstDigit + 1, 1000)) END AS ClaimNoZeroCount
) AS ca2
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I don't understand why you are posting new and new (incorrect) solutions to the question which has the correct solution already.
If you would read all posts then you could note the value AAA0 is possible as the ClaimNo. Of course, the question here is whether to convert it as "AAA " or "AAA 0".
If you would read all posts then you could note the value AAA0 is possible as the ClaimNo. Of course, the question here is whether to convert it as "AAA " or "AAA 0".
Eh ?
Sorry @pcelba, but I did read the posts which is why I continued on with my submission....
"AAA0" is not a legitimate requirement as far as I could ascertain. It was corrected. Maybe you didnt see : #a42655867
Anyway.... As far as "AAA0" is concerned, my submission does cater for it and returns
There would be a problem with (say) "AAA999" which should probably stay as it is, but in my submission it would right justify the number part. So, some additional checking is probably required. But then, we are told there will always be 12 characters. And as mentioned above, we can easily add in some checks.....
Other than that, I dont see why you would call it "(incorrect) solutions"
Sorry @pcelba, but I did read the posts which is why I continued on with my submission....
"AAA0" is not a legitimate requirement as far as I could ascertain. It was corrected. Maybe you didnt see : #a42655867
What I mean is value is equal to AAA000000000.
Anyway.... As far as "AAA0" is concerned, my submission does cater for it and returns
claimno new_claimno
------------ ------------
AAA0 AAA 0
(1 row affected)
After all, I read the requirement as 'leading zeros' so, a single zero should also work.There would be a problem with (say) "AAA999" which should probably stay as it is, but in my submission it would right justify the number part. So, some additional checking is probably required. But then, we are told there will always be 12 characters. And as mentioned above, we can easily add in some checks.....
Other than that, I dont see why you would call it "(incorrect) solutions"
My apology Mark, your code works.
I don't understand why you are posting new and new (incorrect) solutions to the question which has the correct solution already.
Your code will fail -- completely crash -- if the remaining chars are not all numeric. It will miss data if there happen to be more than 9 chars after the first three chars.
OP may be willing to unconditionally guarantee the data will always match the current pattern at the risk of failure. Then again, they may not. I generally prefer code that's as flexible as possible to data changes/variations.
ASKER
Hello Experts,
I really do apologize for a late response. Last Friday, I left work early. I did not have a chance to respond. My sincere apology.
@dbishop:
To answer your questions:
A couple of questions for clarification:
Are you wanting to replace the leading zeroes with spaces, or remove leading zeroes? In other words, should ABC00000123 become ABC123 or ABC 123?
--ABC 123
Are the nine characters after the three letters ALWAYS numeric?
--No sometimes there are 9 letters.
@Scott Pletcher:
I know your query is working. All I need is a simple query. Do I need to create cross apply?
@pcelba:
I still have an error if it is not numeric after the 3 letters. Your query is working also but I don't know how to work around the errors.
@MarkWillis:
Your query perfectly what I needed. It is simple and easy to understand. Mark, where should I put the these: TRY_CAST() if SQL2012, or check ISNUMERIC(), and LEN() > 3. I have SQL Management Studio 2014.
To all experts, please be patient with me, I am not an expert to SQL, I am still learning. I am still trying to learn the logic.
Thank you again for all your help.
I really do apologize for a late response. Last Friday, I left work early. I did not have a chance to respond. My sincere apology.
@dbishop:
To answer your questions:
A couple of questions for clarification:
Are you wanting to replace the leading zeroes with spaces, or remove leading zeroes? In other words, should ABC00000123 become ABC123 or ABC 123?
--ABC 123
Are the nine characters after the three letters ALWAYS numeric?
--No sometimes there are 9 letters.
@Scott Pletcher:
I know your query is working. All I need is a simple query. Do I need to create cross apply?
@pcelba:
I still have an error if it is not numeric after the 3 letters. Your query is working also but I don't know how to work around the errors.
@MarkWillis:
Your query perfectly what I needed. It is simple and easy to understand. Mark, where should I put the these: TRY_CAST() if SQL2012, or check ISNUMERIC(), and LEN() > 3. I have SQL Management Studio 2014.
To all experts, please be patient with me, I am not an expert to SQL, I am still learning. I am still trying to learn the logic.
Thank you again for all your help.
ASKER
Thank you again for sharing your intelligence and expertise to make this query a success. You are all indeed very helpful.
I really appreciate it from the bottom of my heart.
I really appreciate it from the bottom of my heart.
Hi Queenie L,
Well TRY_CAST() will either complete the CAST, or if it cannot, then gives NULL
Have a read of : https://docs.microsoft.com/en-us/sql/t-sql/functions/try-cast-transact-sql?view=sql-server-2017 it does save a lot of mucking about.
In this case, we would use it when casting to INT ie:
The only other problem is checking for LEN(). We should check for len(claimno) > 3 otherwise with the substring() starting at 4, it could fail. There are a couple of strategies that could be used.
One is : CASE WHEN LEN(CLAIMNO) > 3 then <code> end as new_claimno
The other is to simply extend the length of claimno in the substring .: substring(claimno+' ',4,9)
Advantage of checking LEN() is it will account for NULL values
But then, there should probably be a WHERE claimno is not null.
What we strive to do is to 'accommodate' the unexpected errors so the code will work.
Does that explain it ?
Well TRY_CAST() will either complete the CAST, or if it cannot, then gives NULL
Have a read of : https://docs.microsoft.com/en-us/sql/t-sql/functions/try-cast-transact-sql?view=sql-server-2017 it does save a lot of mucking about.
In this case, we would use it when casting to INT ie:
cast(substring(claimno,4,9) as int)
The challenge is, we dont know what is in that substring, so it could fail. Which is why we use try_cast().... But really, the statement is a bit bigger that that, because we are really looking at making it a varchar ie
cast(try_cast(substring(claimno,4,9) as int) as varchar)
Now, if try_cast() fails it returns NULL, and we dont want NULL, we want the original value. Easy enough, wrap it in an ISNULL() check ie
isnull(cast(try_cast(substring(claimno,4,9) as int) as varchar),substring(claimno,4,9))
Which uses the original (sub)string if the try_cast() returns NULL. Which means our new select statement looks like
select claimno, left(claimno,3) + right(space(9) + isnull(cast(try_cast(substring(claimno,4,9) as int) as varchar),substring(claimno,4,9)),9)
from #claims
Now, there is a little "gotcha" that you need to be careful of, and that is to make sure you end up with compatible datatypes for that column. Which is why we wait to check for the NULL result until AFTER we cast to varchar.The only other problem is checking for LEN(). We should check for len(claimno) > 3 otherwise with the substring() starting at 4, it could fail. There are a couple of strategies that could be used.
One is : CASE WHEN LEN(CLAIMNO) > 3 then <code> end as new_claimno
The other is to simply extend the length of claimno in the substring .: substring(claimno+' ',4,9)
Advantage of checking LEN() is it will account for NULL values
But then, there should probably be a WHERE claimno is not null.
What we strive to do is to 'accommodate' the unexpected errors so the code will work.
Does that explain it ?
ASKER
@MarkWillis:
Yes.
Thank you again for your explanation. That helped a lot.
Yes.
Thank you again for your explanation. That helped a lot.
ASKER
Open in new window
Thank you again.