Как извлечь эту определенную подстроку в SQL Server?

У меня есть строка с определенным шаблоном:

23;chair,red [$3]

i.e, число, за которым следует точка с запятой, затем имя, за которым следует левая квадратная скобка.

Предполагая, что точка с запятой ; всегда существует, а левая квадратная скобка [ всегда существует в строке, как мне извлечь текст между (и не включая) ; и [ в SQL Server запрос? Спасибо.

Ответ 1

Объедините функции SUBSTRING(), LEFT() и CHARINDEX().

SELECT LEFT(SUBSTRING(YOUR_FIELD,
                      CHARINDEX(';', YOUR_FIELD) + 1, 100),
                      CHARINDEX('[', YOUR_FIELD) - 1)
FROM YOUR_TABLE;

Это предполагает, что длина вашего поля никогда не будет превышать 100, но вы можете сделать это умнее, чтобы учесть это, если необходимо, используя функцию LEN(). Я не беспокоился, потому что там уже достаточно, и у меня нет экземпляра для тестирования, поэтому я просто просматриваю круглые скобки и т.д.

Ответ 2

Предполагая, что они всегда существуют и не являются частью ваших данных, это будет работать:

declare @string varchar(8000) = '23;chair,red [$3]'
select substring(@string, charindex(';', @string) + 1, charindex(' [', @string) - charindex(';', @string) - 1)

Ответ 3

Альтернатива ответам, предоставленным @Marc

SELECT SUBSTRING(LEFT(YOUR_FIELD, CHARINDEX('[', YOUR_FIELD) - 1), CHARINDEX(';', YOUR_FIELD) + 1, 100)
FROM YOUR_TABLE
WHERE CHARINDEX('[', YOUR_FIELD) > 0 AND
    CHARINDEX(';', YOUR_FIELD) > 0;

Это гарантирует, что разделители существуют, и решает проблему с принятым в настоящее время ответом, где последнее занятие LEFT работает с положением последнего разделителя в исходной строке, а не с пересмотренной подстрокой.

Ответ 4

Если вам нужно разделить что-то на 3 части, например, на адрес электронной почты, и вы не знаете длину средней части, попробуйте это (я просто запустил это на sqlserver 2012, чтобы я знал, что он работает):

SELECT top 2000 
    emailaddr_ as email,
    SUBSTRING(emailaddr_, 1,CHARINDEX('@',emailaddr_) -1) as username,
    SUBSTRING(emailaddr_, CHARINDEX('@',emailaddr_)+1, (LEN(emailaddr_) - charindex('@',emailaddr_) - charindex('.',reverse(emailaddr_)) ))  domain 
FROM 
    emailTable
WHERE 
    charindex('@',emailaddr_)>0 
    AND 
    charindex('.',emailaddr_)>0;
GO

Надеюсь, что это поможет.

Ответ 5

выберите подстроку (your_field, CHARINDEX (';', your_field) +1 , CHARINDEX ( '[', your_field) -CHARINDEX ( ';', your_field) -1) from your_table

Не удается заставить остальных работать. Я считаю, вы просто хотите, что находится между ними; и '[' во всех случаях, независимо от того, насколько длинна строка между ними. После указания поля в подстрочной функции второй аргумент является исходным местоположением того, что вы извлечете. То есть, где ';' + 1 (четвертая позиция - с), потому что вы не хотите включать ';'. Следующий аргумент занимает положение "[" (позиция 14) и вычитает местоположение пятна после ";" (четвертая позиция - вот почему я теперь вычитаю 1 в запросе). Это в основном говорит подстрока (поле, местоположение, которое я хочу, чтобы подстрока начиналась, как долго мне нужна подстрока). Я использовал эту функцию в других случаях. Если в некоторых из полей нет ';' и '[', вы захотите отфильтровать их в предложении "where", но это немного отличается от вопроса. Если ваш ';' было сказано... ';;;', вы должны использовать 3 вместо 1 в примере. Надеюсь это поможет!