sql - 连接中的替换和点赞

标签 sql sql-server-2008

我有两个带有列单词的表tbl_words和带有列关键字的tbl_keywords,表中的示例数据如下

输入:

tbl_words

Word
house for rent in ohio

tbl_keywords

keywords
house
rent

现在我的目标是连接这两个表,并用表 tbl_words 中的空字符串('')替换 tbl_keywords 中的匹配关键字。

所需输出:

tbl_words
Word
for in ohio

Schema creation for the above tables

最佳答案

您可以使用 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”,则需要进行调整。在俄亥俄州',但这可以作为练习留给您完成。

编辑:

根据您的表现,这种方法可能会更好(稍后描述)...

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] 上放置一个(最好是唯一的)索引。

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

关于sql - 连接中的替换和点赞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22142586/

相关文章:

sql-server - 使用导入向导将数据库从 SQL Server 2005 复制到 SQL Server 2008 时出错

php - SQL 使用从另一个表获取的数组从一个表中选择行

sql - 如何在 SQL Server 中拆分破折号分隔值?

java - Cachedrowset、JDBC和SQL Server 2008插入图像问题

sql-server - 报表服务器无法解密用于访问报表服务器数据库中的敏感或加密数据的对称 key SSRS 错误

sql-server - 如何将 xml 编码 <?xml version ="1.0"encoding ="UTF-8"?> 添加到 SQL Server 中的 xml 输出

sql - INSERT into table 和 UPDATE 另一个表中的外键(Sql Server 2008)

mysql - 年薪月薪

.net - 将空白字段值传递给存储过程 ASP .NET C#

sql - 在三个单独的列中计算值 - Rails/SQL