0

这是我遇到的问题。我想返回与我的数据库中的表相似的行。考虑具有以下文本的两行:

'Cisco phones cannot dial out'
'Phones are not working for outgoing calls'

这是两个不同的行......我试图做这样的事情:

DECLARE @TheTest varchar(1000)
DECLARE @TheResult varchar(1000)

SET @TheTest = ('Cisco phones cannot dial out')
SET @TheResult = ('Phones are not working for outgoing calls')

CREATE TABLE #Test
(
MyCol varchar(1000)
)

INSERT INTO #Test(MyCol)
SELECT @TheResult

SELECT * FROM #Test WHERE LOWER(MyCol) LIKE '%' + LOWER(@TheTest) + '%'

DROP TABLE #Test

但结果是返回了 0 行,我明白这是因为字符串 TheTest 与字符串 @TheResult 不够接近……但我需要一个实际返回这一行的解决方案,因为两个文本中都出现了单词 phones。

我是否必须构建更精细的东西来分隔单词并摆脱像这样的常用词?我想模仿我在特定网站上看到的功能:

在此处输入图像描述

4

3 回答 3

2

根据我对您的问题的理解,甚至 SQL FullText 都不会得到您想要的。
您正在寻找 Lucene 类型的功能。
我认为他们在 SO 上使用 Lucene 来寻找类似的问题。

一个捷径是解析单词,然后获取词干 (Porter) 并填充表格。
只是在断词上使用正则表达式是一个开始。
或者你可以跳过词干,但这会错过很多匹配(例如匹配)。
仅索引唯一单词/词干。
如果一个词在一个短语中出现 4 次,在另一个短语中出现 2 次,那么评分就有问题。
而且我认为每个单词一个匹配是一个更有意义的分数。
然后进行连接并计算连接的单词数。
需要规范化,因为 12 个单词的 12 个匹配优于 20 个单词的 14 个匹配。
比如 2 * 匹配 /(字数 A + 字数 B)。

另一个方向是不使用词干,而是使用像 Levenstein 距离这样的模糊匹配。

在您的示例中,只有电话匹配,因此得分较低。
但即使是 Lucene 或 Google 也很难给出高分。
将英语中的两个短语分解为具有不同单词但含义相同的短语是非常复杂的。

于 2012-10-24T14:35:49.170 回答
0

您可能想尝试SOUNDEX返回两个字符串之间的相似性:http: //msdn.microsoft.com/en-us/library/ms187384.aspx

它返回一个保存两个字符串之间相似性的 varchar。然后,您可以评估 varchar 是否在您定义的可接受的“相似性范围”内。

于 2012-10-24T14:11:06.843 回答
0

一种方法是使用一个Split函数(这里是一个演示):

CREATE FUNCTION [dbo].[Split]
(
    @ItemList NVARCHAR(MAX), 
    @delimiter CHAR(1)
)
RETURNS @IDTable TABLE (Item VARCHAR(50))  
AS      

BEGIN    
    DECLARE @tempItemList NVARCHAR(MAX)
    SET @tempItemList = @ItemList

    DECLARE @i INT    
    DECLARE @Item NVARCHAR(4000)

    SET @i = CHARINDEX(@delimiter, @tempItemList)

    WHILE (LEN(@tempItemList) > 0)
    BEGIN
        IF @i = 0
            SET @Item = @tempItemList
        ELSE
            SET @Item = LEFT(@tempItemList, @i - 1)
        INSERT INTO @IDTable(Item) VALUES(@Item)
        IF @i = 0
            SET @tempItemList = ''
        ELSE
            SET @tempItemList = RIGHT(@tempItemList, LEN(@tempItemList) - @i)
        SET @i = CHARINDEX(@delimiter, @tempItemList)
    END 
    RETURN
END  

现在您可以检查列中是否包含其中一个单词:

DECLARE @TheTest varchar(1000)
DECLARE @TheResult varchar(1000)

SET @TheTest = ('Cisco phones cannot dial out')
SET @TheResult = ('Phones are not working for outgoing calls')

CREATE TABLE #Test
(
MyCol varchar(1000)
)

INSERT INTO #Test(MyCol)
    SELECT @TheResult

Declare  @searchWords Table(Item varchar(100));
INSERT INTO @searchWords
    SELECT Item FROM dbo.Split(@TheTest, ' ');

SELECT * FROM #Test t
WHERE EXISTS
(
    SELECT 1 
    FROM dbo.Split(t.MyCol, ' ')cw INNER JOIN @searchWords sw
        ON cw.Item = sw.Item
);

DROP TABLE #Test 
于 2012-10-24T14:22:26.153 回答