SQL - 根据搜索模式输出子字符串,确保第一个/最后一个字符串是完整的单词

时间:2009-12-03 12:39:54

标签: sql sql-server tsql

我在XMLData类型列中搜索了以下查询。

我想返回一个节点的子字符串,该节点以搜索条件开头,后面以一个完整的单词或子字符串结束的X个字符,将搜索条件放在结果的中间,前面加上X个字符在开始/结束一个新词之后。

2个概念的原因是搜索条件可能位于节点的开头,因此之后的X个字符或者如果在文本的深处显示前/后字符。

我的查询似乎是从一个新单词开始,但是我不能在结束它,我有一个反转字符串,对它做一个patindex然后做搜索的长度 - patindex但似乎没有工作

由于

SELECT 
P.Title,
SUBSTRING(DATA.value('(/PageContent/Text)[1]', 'VARCHAR(100)'),PATINDEX('%north%',DATA.value('(/PageContent/Text)[1]', 'VARCHAR(100)')) - 20 + PATINDEX('% %',SUBSTRING(DATA.value('(/PageContent/Text)[1]', 'VARCHAR(100)'),PATINDEX('%north%',DATA.value('(/PageContent/Text)[1]', 'VARCHAR(100)')) - 20,999)),999) AS Data

FROM WEBPAGECONTENT W

INNER JOIN WebPage P
ON P.ID = W.PageID

WHERE COALESCE(PATINDEX('%north%',DATA.value('(/PageContent/Text)[1]', 'VARCHAR(100)')),0) > 0

1 个答案:

答案 0 :(得分:0)

放手一搏。我用简单的变量替换了你的XML查询,但语句的基本布局保持不变。尽管如此,这有点像熊。此外,根据您的数据和要求,您可能希望更改搜索单个空格以包含其他字符,例如“。”和','作为单词的潜在目的。

尽管我想解释代码的每一点,但它已经过了我的午餐时间,所以我将把它作为读者的练习;)

DECLARE
 @search_string VARCHAR(20),
 @string   VARCHAR(1000)

SET @string = 'This is a test north this is only a test'
SET @search_string = 'north'

SELECT
 SUBSTRING(@string,
 CASE
  WHEN PATINDEX('%' + @search_string + '%', @string) <= 20 THEN 1
  WHEN PATINDEX('% %', SUBSTRING(@string, PATINDEX('%' + @search_string + '%', @string) - 20, 20)) <> 0
   THEN PATINDEX('% %', SUBSTRING(@string, PATINDEX('%' + @search_string + '%', @string) - 20, 20))
  ELSE PATINDEX('%' + @search_string + '%', @string)
 END,
 CASE
  WHEN PATINDEX('%' + @search_string + '%', @string) + LEN(@search_string) >= LEN(@string) - 20 THEN 1000
  WHEN PATINDEX('% %', SUBSTRING(@string, PATINDEX('%' + @search_string + '%', @string) + LEN(@search_string), 20)) <> 0
   THEN PATINDEX('% %', SUBSTRING(@string, PATINDEX('%' + @search_string + '%', @string) + LEN(@search_string), 20))
  ELSE 0
 END + LEN(@search_string) +
 (PATINDEX('%' + @search_string + '%', @string) - CASE
  WHEN PATINDEX('%' + @search_string + '%', @string) <= 20 THEN 1
  WHEN PATINDEX('% %', SUBSTRING(@string, PATINDEX('%' + @search_string + '%', @string) - 20, 20)) <> 0
   THEN PATINDEX('% %', SUBSTRING(@string, PATINDEX('%' + @search_string + '%', @string) - 20, 20))
  ELSE PATINDEX('%' + @search_string + '%', @string)
 END)
)