Извлечение вложенной строки из строки в sql sever

#sql-server #string #substring #charindex

#sql-сервер #строка #подстрока #charindex

Вопрос:

У меня есть следующие строковые значения в столбце в таблице базы данных SQL server:

 CS-NO2-T6082 BROWN,STORAGE       
CS-NO2-T6082 BROWN                      
CS-CT2N64045,POW REC X 2,ROCKER         
CONSOLE,CS-CT2N74045,POW REC X 2        
CS
CS,MAN REC   
CS-T6082,POW REC X 2                                               
CS-CT12N1176   
CS-NO2-T6082 BROWN,SQUARE  
CS-CT12N1176                                                                  
CS-2T1176 GREY  
  

Я пытаюсь получить значения только тогда, когда им предшествует ‘CS’, но есть несколько случаев, как показано в приведенных выше примерах. ‘CS’ может отображаться самостоятельно или с номером, разделенным символом ‘-‘, а затем цветом, разделенным пробелом. Это может быть в начале строки, в середине или в конце. Я хочу сначала проверить, есть ли в столбце только одно значение, проверив наличие запятой, если есть только одно значение и оно содержит слово «CS», тогда это выглядит просто. Но когда по обе стороны от интересующей строки имеется несколько значений, это становится проблемой.

Я буду признателен за любые предложения или решения в sql server, пожалуйста.

Результат должен выглядеть следующим образом:

 CS-NO2-T6082 BROWN       
CS-NO2-T6082 BROWN                      
CS-CT2N64045        
CS-CT2N74045        
CS
CS   
CS-T6082                                               
CS-CT12N1176   
CS-NO2-T6082 BROWN  
CS-CT12N1176                                                                  
CS-2T1176 GREY 
  

Спасибо.

Ответ №1:

Вы можете использовать CHARINDEX LEFT функцию string

CHARINDEX — Помогает определить первое вхождение comma amp; CS в строке

SUBSTRING — Извлечение строки из CS первого вхождения запятой в строке

 SELECT org_string, 
       Result_string = substring(org_string,pos,CASE WHEN Charindex(',', org_string,pos 1) <> 0 then Charindex(',', org_string,pos 1)-pos else len(org_string) end)
FROM   ( VALUES ('CS-NO2-T6082 BROWN,STORAGE' ), 
                ('CS-NO2-T6082 BROWN' ), 
                ('CS-CT2N64045,POW REC X 2,ROCKER' ), 
                ('CONSOLE,CS-CT2N74045,POW REC X 2' ), 
                ('CS' ), 
                ('CS,MAN REC' ), 
                ('CS-T6082,POW REC X 2' ), 
                ('CS-CT12N1176' ), 
                ('CS-NO2-T6082 BROWN,SQUARE' ), 
                ('CS-CT12N1176' ), 
                ('CS-2T1176 GREY')) cs (org_string) 
                cross apply (values (charindex('CS',org_string))) p (pos)
  

Результат :

 ╔══════════════════════════════════╦════════════════════╗
║            org_string            ║   Result_string    ║
╠══════════════════════════════════╬════════════════════╣
║ CS-NO2-T6082 BROWN,STORAGE       ║ CS-NO2-T6082 BROWN ║
║ CS-NO2-T6082 BROWN               ║ CS-NO2-T6082 BROWN ║
║ CS-CT2N64045,POW REC X 2,ROCKER  ║ CS-CT2N64045       ║
║ CONSOLE,CS-CT2N74045,POW REC X 2 ║ CS-CT2N74045       ║
║ CS                               ║ CS                 ║
║ CS,MAN REC                       ║ CS                 ║
║ CS-T6082,POW REC X 2             ║ CS-T6082           ║
║ CS-CT12N1176                     ║ CS-CT12N1176       ║
║ CS-NO2-T6082 BROWN,SQUARE        ║ CS-NO2-T6082 BROWN ║
║ CS-CT12N1176                     ║ CS-CT12N1176       ║
║ CS-2T1176 GREY                   ║ CS-2T1176 GREY     ║
╚══════════════════════════════════╩════════════════════╝
  

Комментарии:

1. 4-й результат (КОНСОЛЬ) неверен. В середине отсутствует CS-значение.

Ответ №2:

Вы можете сделать это за 2 прохода. Первый ищет ‘CS-‘ или ‘CS’. Второй ищет запятую и возвращает только текст перед ней (или всю строку целиком, если запятой нет).

 SELECT CASE WHEN CHARINDEX(',',Result1)>0 THEN LEFT(Result1,CHARINDEX(',',Result1)-1)
            ELSE Result1
       END AS FinalResult
FROM 
  (SELECT CASE WHEN CHARINDEX('CS-',[Orig_String])>0 THEN SUBSTRING([Orig_String],CHARINDEX('CS-',[Orig_String]), LEN([Orig_String]))
               ELSE [Orig_String]          
          END AS Result1
  FROM [Table1]) AS T
  

Ответ №3:

Интересное бизнес-требование, протестируйте приведенный ниже сценарий, это почти решит вашу проблему.

 SELECT CASE WHEN CHARINDEX(',',ColName) = 0 THEN ColName
        WHEN CHARINDEX('CS',ColName) < CHARINDEX(',',ColName) THEN LEFT(ColName,CHARINDEX(',',ColName)-1) 
        WHEN CHARINDEX('CS',ColName) > CHARINDEX(',',ColName) THEN PARSENAME(REPLACE(ColName,',','.'),2) 
        END
From TableName