不能使用LIKE所以我可以使用什么

时间:2012-10-24 14:07:28

标签: sql-server tsql

这是我遇到的问题。我想从我的数据库中的表中返回类似的行。 考虑两行,其中包含以下文本:

'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不够接近......但我需要一个实际上会返回此行的解决方案,因为单词phone出现在文本。

我是否需要构建一些更精细的内容来分离单词并摆脱常见的单词?我想模仿我在特定网站上看到的功能:

enter image description here

3 个答案:

答案 0 :(得分:2)

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

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

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

在您的示例中,只有手机匹配才能得分较低 但即使是Lucene或Google也无法给出高分 分解两个具有不同单词但意思相同的短语的英语非常复杂。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

一种方法是使用Split函数(here's a demo):

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