0

I have a data as follows

+-------+----------------------------------------------+
| ID    | COMMENT                                      |
+-------+----------------------------------------------+
| 3118- | Replace Id.NO 3117-52-96 Was wrongly updated |
+-------+----------------------------------------------+
| 4857  | Replace Id.NO.4875-21-96-due to 2 mistake    |
+-------+----------------------------------------------+
| 5877  | replace .ID NO 5876.69.49 due mistake 101    |
+-------+----------------------------------------------+
| 1254  | Replace Id No. 1259-93-87 due to mistake 81  |
+-------+----------------------------------------------+

I want to get the values after the No and before some words. Something like below

+-------+----------------------------------------------+------------+
| ID    | COMMENT                                      | NEW_VALUE  |
+-------+----------------------------------------------+------------+
| 3118- | Replace Id.NO 3117-52-96 Was wrongly updated | 3117-52-96 |
+-------+----------------------------------------------+------------+
| 4857  | Replace Id.NO.4875-21-96-due to mistake      | 4875-21-96 |
+-------+----------------------------------------------+------------+
| 5877  | replace .ID NO 5876.69.49 due mistake        | 5876.69.49 |
+-------+----------------------------------------------+------------+
| 1254  | Replace Id No. 1259-93-87 due to mistake     | 1259-93-87 |
+-------+----------------------------------------------+------------+

Then I have to update the ID column with NEW_VALUE. Once I get the NEW_VALUE, it will be easy to update.

What I have tried.

SELECT ID,COMMENT,
REPLACE(REPLACE(COMMENT,'Replace Id.NO',''),'Replace Id.NO.','')FROM MYTABLE

Like above i'm using multiple(around 10) REPLACE to get my required value. I'm sure there should be some easy way.

6
  • What if the comment has two "No."s? Commented Jan 16, 2020 at 12:31
  • @GordonLinoff. It will have only one No. Commented Jan 16, 2020 at 12:32
  • What characters are permissable? I notice that both - and . are ok. What about / or ' ' (a single white space)? if ' ' is "ok", what would you expect to see if something like the string 'Replace ID no 123 456 789 2 orders were wrong'? Is a "No" always 3 blocks of numbers? Commented Jan 16, 2020 at 12:33
  • @Larnu, "No" will have some separator. There will not be any empty separater. It may be 3 or max 4 blocks but with some separator. Commented Jan 16, 2020 at 12:36
  • So what separators could it be? What is a permissible seperator? Commented Jan 16, 2020 at 12:44

2 Answers 2

3

One suggestion:

SELECT V.ID,
       V.Comment,
       SUBSTRING(V.Comment,PI.I+3,CI.I) AS NewComment
FROM (VALUES(3118,'Replace Id.NO 3117-52-96 Was wrongly updated'),
            (4857,'Replace Id.NO.4875-21-96-due to 2 mistake'),
            (5877,'replace .ID NO 5876.69.49 due mistake 101'),
            (1254,'Replace Id No. 1259-93-87 due to mistake 81'))V(ID,Comment)
      CROSS APPLY (VALUES(PATINDEX('%No[ .]%', V.Comment)))PI(I)
      CROSS APPLY (VALUES(PATINDEX('%[^0-9.-]%',STUFF(V.Comment,1,PI.I+3,'')))) CI(I);

This uses PATINDEX to find the Position of 'No '/'No.', and then the first position of a character that isn't a number of delimiter (0-9 or a . or - character).

Note that for the string 'Replace Id.NO.4875-21-96-due to 2 mistake' the value '4875-21-96-' is returned, due to the trailing delimiter on the value.

Ideally, what you need to be doing is fixing your design here, which I assume is why you are undertaking this. As a result you'll likely need to manually "mop up" any anonalies due to the poor data.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks a lot @Larnu. This is neat. It is working for all except when the string is like Replace Id No . 1265-92-87 due to mistake 81. space after No and before .. is there any way to fix that. If not i will do that one with REPLACE not a problem.
Also can you please explain me PI.I+3. Not able to get that
I expected some consistency to your data, @Avinash . You could use REPLACE to fix the really bad data first, yes.
+3 means add 3 to the value of PI.I.
1

You can use PATINDEX() :

SELECT mt.id, mt.COMMENT, SUBSTRING(mt.comment, PATINDEX('%[0-9]%', mt.comment)-1, 10)
FROM MYTABLE mt;

This will assumes comment have only one number & contains 10 length.

EDIT :

SELECT mt.id, mt.COMMENT, SUBSTRING(mtt.comments, 1, PATINDEX('%[A-Z]%', mtt.comments)-2)
FROM MYTABLE mt CROSS APPLY
     ( VALUES (SUBSTRING(mt.comment, PATINDEX('%[0-9]%', mt.comment), LEN(mt.comment)))
     ) tt(comments)

5 Comments

Unfortunately , The length is not always 10. it can vary from 7-10 .In those cases i'm getting wrong output.
@Avinash. . . In that case you can use APPLY.
Thanks for the efforts. But it is giving me the strings after the number. Something like Was wrongly updated
@Avinash. . Ohh yes. Updated
Can you please help me with this question as well . I'm looking for some clue from 2 days but couldn't get. @Yogesh

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.