这是我遇到的问题。我想从我的数据库中的表中返回类似的行。 考虑两行,其中包含以下文本:
'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出现在文本。
我是否需要构建一些更精细的内容来分离单词并摆脱常见的单词?我想模仿我在特定网站上看到的功能:
答案 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