Выберите часть строки и обновите сервер SQL - PullRequest
0 голосов
/ 16 января 2020

У меня есть данные следующим образом

+-------+----------------------------------------------+
| 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  |
+-------+----------------------------------------------+

Я хочу получить значения после No и перед некоторыми словами. Что-то вроде ниже

+-------+----------------------------------------------+------------+
| 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 |
+-------+----------------------------------------------+------------+

Затем я должен обновить столбец ID с NEW_VALUE. Как только я получу NEW_VALUE, его будет легко обновить.

То, что я пробовал.

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

Как и выше, я использую несколько ( около 10 ) REPLACE чтобы получить требуемое значение. Я уверен, что должен быть какой-то легкий путь.

Ответы [ 2 ]

3 голосов
/ 16 января 2020

Одно предложение:

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);

При этом используется PATINDEX, чтобы найти позицию 'No ' / 'No.', а затем первую позицию символа, который не номер разделителя (0-9 или . или - символ).

Обратите внимание, что для строки 'Replace Id.NO.4875-21-96-due to 2 mistake' возвращается значение '4875-21-96-' из-за конечного разделителя на значение.

В идеале, то, что вам нужно сделать, это исправить свой дизайн здесь, и я предполагаю, что именно поэтому вы беретесь за это. В результате вам, вероятно, придется вручную «убирать» любые аномалии из-за плохих данных.

1 голос
/ 16 января 2020

Вы можете использовать PATINDEX():

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

Предполагается, что комментарий имеет только одно число и содержит 10 длин.

РЕДАКТИРОВАТЬ:

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)
...