在联接中替换和喜欢

时间:2014-03-03 09:10:04

标签: sql sql-server-2008

我有两个表tbl_words包含列字,tbl_keywords包含列关键字,表中的示例数据如下所示

Input:

tbl_words

Word
house for rent in ohio

tbl_keywords

keywords
house
rent

现在我的目标是将这两个表格和替换来自tbl_keywords的匹配关键字与表格tbl_words中的空字符串('')结合起来。

期望输出:

tbl_words
Word
for in ohio

Schema creation for the above tables

2 个答案:

答案 0 :(得分:4)

您可以使用CTE循环覆盖所有单词并用空格替换所有单词。

在这里演示http://sqlfiddle.com/#!3/7563a/21

WITH CTE (org, calc, DATA, level) AS
(
    SELECT word, word, CONVERT(VARCHAR(500), ' ' + word + ' '), 0
    FROM    tbl_words

    UNION ALL

    SELECT CTE.org, CTE.data,
        CONVERT(VARCHAR(500), REPLACE(CTE.data, tbl_keywords.Keyword + ' ', '')), CTE.level + 1
    FROM    CTE
    INNER JOIN tbl_keywords ON CTE.data LIKE '% ' + tbl_keywords.Keyword + ' %'
        COLLATE Latin1_General_CS_AS
)
SELECT DISTINCT org, LTRIM(RTRIM(data)) AS DATA, level
FROM CTE
WHERE level =
    (SELECT MAX(level) FROM CTE c WHERE CTE.org = c.org)

在每个单词的开头和结尾添加' '是为了让您'acters'之类的字词不会影响'characters',否则就会变成'char'。它还可以防止在短语中间处理多个空格字符,例如' for in ohio'

如果你的遗产中有标点符号,例如'houses for sale. in ohio',则需要对此进行调整,但这可以留作练习让你完成。

编辑:

取决于你的表现,这种方法可能会更好(后面的描述)......

create function [dbo].[Split] 
( 
    @string nvarchar(MAX), 
    @delimiter nvarchar(10) 
) 
returns @table table 
( 
    [Value] nvarchar(MAX) 
) 
begin 
    declare @nextString nvarchar(MAX) 
    declare @pos int, @nextPos int 
    declare @commaCheck nvarchar(1) 

    set @nextString = '' 
    set @commaCheck = right(@string, 1) 
    set @string = @string + @delimiter 

    set @pos = charindex(@delimiter, @string) 
    set @nextPos = 1 
    while (@pos <> 0) 
    begin 
        set @nextString = substring(@string, 1, @pos - 1) 

        insert into @table 
        ( 
            [Value] 
        ) 
        values 
        ( 
            @nextString 
        ) 

        set @string = substring(@string, @pos + 1, len(@string)) 
        set @nextPos = @pos 
        set @pos = charindex(@delimiter, @string) 
    end 
    return 
end

现在查询变为:

SELECT RTRIM(combined) AS [words] FROM
(SELECT word, 
(
select [value] + ' ' as [text()]
from dbo.split(word, ' ')
where [value] not in (SELECT [keyword] from tbl_keywords)
FOR XML PATH('')
)
 as [combined] 
from tbl_words) x;

基本上我们将短语拆分为单个单词,删除关键单词,然后使用FOR XML PATH将它们连接在一起。

在我的系统上运行速度提高了6倍,但这取决于你的短语有多长,以及你有多少单词。为了进一步提高性能,在[tbl_keywords]上设置了一个(理想的唯一)索引。[keyword]。

同样,这不适用于标点符号,因此如果需要,您需要相应地调整所有内容。

答案 1 :(得分:0)

SELECT replace(w.word, k.keyword, '') as REPLACED_KEYWORDS
FROM #tbl_words w
JOIN #tbl_keywords k
ON w.word LIKE '%' + k.keyword + '%'

<强> SEE DEMO