2013-08-21 2 views
17

Мне нужен SQL-запрос для получения значения между двумя известными строками (возвращаемое значение должно начинаться и заканчиваться этими двумя строками).SQL Query для выбора строки между двумя известными строками

Пример.

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

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

я пришел с этим до сих пор, но безрезультатно:

SELECT SUBSTRING(@Text, CHARINDEX('the dog', @Text), CHARINDEX('immediately', @Text)) 

@Text является переменная, содержащая основная строка.

Может кто-нибудь, пожалуйста, помогите мне с тем, где я ошибаюсь?

+1

Какую ошибку вы получаете или что возвращается? – eatonphil

+0

«Собака была очень плоха и требовала жесткого наказания, немедленно расследующего» –

ответ

31

Проблема заключается в том, что вторая часть вашего подстроки аргумента включая первый индекс. Чтобы сделать эту работу, вам нужно вычесть первый индекс из вашего второго индекса.

SELECT SUBSTRING(@Text, CHARINDEX('the dog', @Text) 
, CHARINDEX('immediately',@text) - CHARINDEX('the dog', @Text) + Len('immediately')) 
+3

Это работает, если книжные знаки, которые вы ищете, появляются только один раз, но если они появляются более одного раза. – samthebrand

5

Вам нужно настроить для ДЛИНЫ в ПОДПИСАНИИ. Вы указывали его на конец конечной строки.

попробовать что-то вроде этого:

declare @TEXT varchar(200) 
declare @ST varchar(200) 
declare @EN varchar(200) 
set @ST = 'the dog' 
set @EN = 'immediately' 
set @TEXT = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.' 
SELECT SUBSTRING(@Text, CHARINDEX(@ST, @Text), (CHARINDEX(@EN, @Text)+LEN(@EN))-CHARINDEX(@ST, @Text)) 

Конечно, вам может потребоваться настроить его немного.

2

У меня такое чувство, что вам может понадобиться функция SQL Server PATINDEX(). Проверьте это:

Usage on Patindex() function

Так, может быть:

SELECT SUBSTRING(@TEXT, PATINDEX('%the dog%', @TEXT), PATINDEX('%immediately%',@TEXT)) 
2
DECLARE @Text VARCHAR(MAX), @First VARCHAR(MAX), @Second VARCHAR(MAX) 
SET @Text = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.' 
SET @First = 'the dog' 
SET @Second = 'immediately' 

SELECT SUBSTRING(@Text, CHARINDEX(@First, @Text), 
       CHARINDEX(@Second, @Text) - CHARINDEX(@First, @Text) + LEN(@Second)) 
4

Я думаю, что Эван имел в виду это:

SELECT SUBSTRING(@Text, CHARINDEX(@First, @Text) + LEN(@First), 
       CHARINDEX(@Second, @Text) - CHARINDEX(@First, @Text) - LEN(@First)) 
+0

Не совсем то, что задал ОП: этот ответ разбивает строки на край. Но это полезный фрагмент. – samthebrand

1

Вы «немедленно наказание» получать начальное положение, но попутно, что в качестве параметра длины для вашей подстроки.

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

Вот некоторые грубые, Hacky код, чтобы проиллюстрировать процесс:

DECLARE @text VARCHAR(MAX) 
SET @text = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.' 

DECLARE @start INT 
SELECT @start = CHARINDEX('the dog',@text) 

DECLARE @endLen INT 
SELECT @endLen = LEN('immediately') 

DECLARE @end INT 
SELECT @end = CHARINDEX('immediately',@text) 
SET @end = @end - @start + @endLen 

SELECT @end 

SELECT SUBSTRING(@text,@start,@end) 

Результат: собака была очень плохо и требуется суровое наказание немедленно

2

Попробуйте это и заменить «[» & ']' с вашей строкой

SELECT SUBSTRING(@TEXT,CHARINDEX('[',@TEXT)+1,(CHARINDEX(']',@TEXT)-CHARINDEX('[',@TEXT))-1) 
6

exa mple заключается в следующем: У вас есть строки и символ $

Строка:

aaaaa$bbbbb$ccccc 

Код:

SELECT SUBSTRING('aaaaa$bbbbb$ccccc',CHARINDEX('$','aaaaa$bbbbb$ccccc')+1, CHARINDEX('$','aaaaa$bbbbb$ccccc',CHARINDEX('$','aaaaa$bbbbb$ccccc')+1) -CHARINDEX('$','aaaaa$bbbbb$ccccc')-1) as My_String 

Выход:

bbbbb 
+0

Что делать, если у вас есть что-то вроде 'aaaaa $ bbbbb $ cc $ ccc $ '', и вы хотите, чтобы он возвращал 2 строки, содержащие 'bbbbb & ccc'? –

+1

Для первой строки, которую я выбрал, это нормально. Для второго (aaaaa $ bbbbb $ cc $ ccc): выберите reverse (left (reverse ('aaaaa $ bbbbb $ cc $ ccc'), charindex ('$', reverse ('aaaaa $ bbbbb $ cc $ ccc ')) -1)) –

+0

Это не отвечает на вопрос, так как предполагает, что «букранды» строки OP являются одним и тем же символом, что неверно. – samthebrand

0

Надеюсь, что это поможет: Объявлена ​​переменная, в случае каких-либо изменений необходимо сделать это только один раз.

объявляют @line VARCHAR (100)

множество @line ='[email protected]»

выберите SUBSTRING (@line, (CHARINDEX ('-', @ линия) +1), CHARINDEX ('@', @ линия) -charindex ('-', @ линия) -1)

+0

Не могли бы вы добавить более подробное объяснение того, что делает ваш запрос, что сделает ваш ответ более полезным. Добро пожаловать в StackOverflow. –

-1
<pre> 

DECLARE @text УАКСНАК (МАКС)

SET @text = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.' 

declare @pretext as nvarchar(100) = 'the dog'  
declare @posttext as nvarchar(100) = 'immediately' 

SELECT 
CASE 
When CHARINDEX(@posttext, @Text) - (CHARINDEX(@pretext, @Text) + len(@pretext)) < 0 THEN 
'' 
Else 
SUBSTRING(@Text, CHARINDEX(@pretext, @Text) + len(@pretext) 
, CHARINDEX(@posttext, @Text) - (CHARINDEX(@pretext, @Text) + len(@pretext)))  
END as betweentext 

+1

Хотя этот фрагмент кода приветствуется и может оказать некоторую помощь, было бы [значительно улучшено, если бы оно включало объяснение] (// meta.stackexchange.com/q/114762) из ​​* how * и * why *, это решает проблема. Помните, что вы отвечаете на вопрос читателей в будущем, а не только на человека, который спрашивает сейчас! Пожалуйста, отредактируйте свой ответ, чтобы добавить объяснение, и укажите, какие ограничения и допущения применяются. –

0

У меня была аналогичная необходимость в анализе набора параметров, хранящихся в поле csUriQuery журналов IIS, которое выглядело так: id=3598308&user=AD\user&parameter=1&listing=No, необходимый в this format.

я в конечном итоге создание определенного пользователя функции для выполнения строки между ними, при следующих допущениях:

  1. Если исходное явление не найдено, NULL возвращается, и
  2. , если окончание Проявление не найден, то оставшаяся часть строки возвращается

Вот код:

CREATE FUNCTION dbo.str_between(@col varchar(max), @start varchar(50), @end varchar(50)) 
    RETURNS varchar(max) 
    WITH EXECUTE AS CALLER 
AS 
BEGIN 
    RETURN substring(@col, charindex(@start, @col) + len(@start), 
     isnull(nullif(charindex(@end, stuff(@col, 1, charindex(@start, @col)-1, '')),0), 
     len(stuff(@col, 1, charindex(@start, @col)-1, ''))+1) - len(@start)-1); 
END; 
GO 

Для приведенного выше вопроса, использование выглядит следующим образом:

DECLARE @a VARCHAR(MAX) = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.' 
SELECT dbo.str_between(@a, 'the dog', 'immediately') 
-- Yields' had been very bad and required harsh punishment ' 
Смежные вопросы