2013-08-21 33 views
17

Tôi cần một truy vấn SQL để lấy giá trị giữa hai chuỗi đã biết (giá trị trả về sẽ bắt đầu và kết thúc bằng hai chuỗi này).Truy vấn SQL để chọn một chuỗi giữa hai chuỗi đã biết

Ví dụ.

"Tất cả những gì tôi biết là con chó đã rất xấu và yêu cầu trừng phạt khắc nghiệt ngay lập tức bất kể người khác nghĩ gì."

Trong trường hợp này, các chuỗi đã biết là "con chó" và "ngay lập tức". Vì vậy, câu hỏi của tôi nên trở về "con chó đã rất xấu và yêu cầu trừng phạt khắc nghiệt ngay lập tức"

tôi đã đi lên với điều này cho đến nay nhưng không có kết quả:

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

@Text là biến chứa chuỗi chính.

Ai đó có thể giúp tôi với nơi tôi đang đi sai không?

+1

Lỗi nào bạn đang nhận hoặc trả lại? – eatonphil

+0

"con chó đã rất xấu và yêu cầu trừng phạt khắc nghiệt ngay lập tức quan tâm" –

Trả lời

31

Vấn đề là phần thứ hai của tham số chuỗi con của bạn là bao gồm các chỉ số đầu tiên. Bạn cần trừ chỉ mục đầu tiên khỏi chỉ mục thứ hai của mình để thực hiện công việc này.

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

Điều này làm việc nếu bookends bạn đang tìm kiếm chỉ xuất hiện một lần, nhưng không nếu chúng xuất hiện nhiều hơn một lần. – samthebrand

5

Bạn cần điều chỉnh LENGTH trong SUBSTRING. Bạn đã trỏ nó đến END của 'chuỗi kết thúc'.

Hãy thử một cái gì đó như thế này:

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

Tất nhiên, bạn có thể cần phải điều chỉnh nó một chút.

2

Tôi có cảm giác rằng bạn có thể cần hàm PATINDEX() của SQL Server. Check this out:

Usage on Patindex() function

Vì vậy, có lẽ:

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

Tôi nghĩ rằng những gì Evan nghĩa là thế này:

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

Không chính xác những gì OP hỏi: câu trả lời này sẽ loại bỏ các chuỗi trên cạnh. Nhưng đây là một đoạn trích hữu ích. – samthebrand

1

Bạn đang nhận vị trí bắt đầu của 'trừng phạt ngay lập tức, nhưng đi qua rằng trong khi các thông số chiều dài cho chuỗi con của bạn.

Bạn sẽ cần phải trừ vị trí bắt đầu của 'con chó' khỏi charindex của 'trừng phạt ngay lập tức', và sau đó thêm chiều dài của chuỗi 'phạt ngay lập tức' vào tham số thứ ba của bạn. Điều này sau đó sẽ cung cấp cho bạn văn bản chính xác.

Dưới đây là một số khó khăn, mã hacky để minh họa quá trình:

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) 

Kết quả: con chó đã rất xấu và yêu cầu trừng phạt khắc nghiệt ngay

2

Hãy thử điều này và thay thế '[' & ']' với chuỗi của bạn

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

Một exa mple là thế này: Bạn có một chuỗi và các nhân vật $

Chuỗi:

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 

Output:

bbbbb 
+0

Nếu u có thứ gì đó như ''aaaaa $ bbbbb $ cc $ ccc $'' và bạn muốn nó trả lại 2 hàng chứa 'bbbbb & ccc'? –

+1

Đối với hàng đầu tiên, lựa chọn tôi đã cung cấp là ok. Đối với số thứ hai (aaaaa $ bbbbb $ cc $ ccc): chọn đảo ngược (trái (đảo ngược ('aaaaa $ bbbbb $ cc $ ccc'), charindex ('$', đảo ngược ('aaaaa $ bbbbb $ cc $ ccc ')) -1)) –

+0

Điều này không thực sự trả lời câu hỏi, vì nó giả định "bookends" của chuỗi OPs là cùng một ký tự, điều này không đúng. – samthebrand

0

Hy vọng điều này sẽ giúp: Đã khai báo biến, trong trường hợp có bất kỳ thay đổi nào cần thực hiện chỉ một lần.

khai báo @line varchar (100)

bộ @line ='[email protected]'

chọn SUBSTRING (@line, (charindex ('-', @ dòng) +1), CHARINDEX ('@', @ line) -charindex ('-', @ dòng) -1)

+0

Bạn có thể thêm nhiều giải thích về truy vấn của mình đang làm hay không, điều đó sẽ giúp câu trả lời của bạn hữu ích hơn. Chào mừng bạn đến với StackOverflow. –

-1
<pre> 

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

Trong khi đoạn mã này được chào đón, và có thể cung cấp một số trợ giúp, nó sẽ được [cải thiện rất nhiều nếu nó bao gồm một lời giải thích] (// meta.stackexchange.com/q/114762) của * how * và * why * this giải quyết vấn đề. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ là người hỏi ngay bây giờ! Vui lòng [sửa] câu trả lời của bạn để thêm giải thích và đưa ra chỉ dẫn về những giới hạn và giả định được áp dụng. –

0

Tôi đã có một nhu cầu tương tự để phân tích một tập hợp các tham số được lưu trữ trong trường 'csUriQuery của nhật ký IIS', trông giống như sau: id=3598308&user=AD\user&parameter=1&listing=No cần thiết trong this format.

tôi đã kết thúc việc tạo ra một chức năng người dùng định nghĩa để thực hiện một chuỗi giữa, với các giả định sau:

  1. Nếu xảy ra bắt đầu không được tìm thấy, một NULL được trả lại, và
  2. Nếu kết thúc xảy ra không được tìm thấy, phần còn lại của chuỗi được trả về

Dưới đây là các mã:

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 

Đối với câu hỏi trên, mức sử dụng như sau:

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 ' 
Các vấn đề liên quan