#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