Sql server 2005 SQL Server全文搜索-创建一个计算列
我目前正在从事一个项目,我想通过一个输入搜索词搜索员工。为此,我使用了SQLFTS 表架构如下所示 员工表 EmployeeId,名字,姓氏 样本数据 约翰,米勒 2,查克,诺里斯Sql server 2005 SQL Server全文搜索-创建一个计算列,sql-server-2005,tsql,full-text-search,Sql Server 2005,Tsql,Full Text Search,我目前正在从事一个项目,我想通过一个输入搜索词搜索员工。为此,我使用了SQLFTS 表架构如下所示 员工表 EmployeeId,名字,姓氏 样本数据 约翰,米勒 2,查克,诺里斯 地址表 地址ID、雇员ID、城市ID、街道、街道号 样本数据 12号大街1号,1号,1号 温布尔登路2号,2号,2号,12号 城市表 城市ID、名称、ZipCode 样本数据 汉堡,22335 伦敦,12345 现在我得到了以下搜索词: 约翰·汉堡:指约翰和汉堡,应返回1张唱片 John London:表示J
地址表 地址ID、雇员ID、城市ID、街道、街道号 样本数据 12号大街1号,1号,1号 温布尔登路2号,2号,2号,12号
城市表 城市ID、名称、ZipCode 样本数据 汉堡,22335 伦敦,12345
现在我得到了以下搜索词:
- 约翰·汉堡:指约翰和汉堡,应返回1张唱片
- John London:表示John和London,由于伦敦没有John,因此应返回0条记录
- 诺里斯温布尔登:指诺里斯和温布尔登,应返回1条记录
SELECT
(keyTblSp.RANK * 3) AS [Rank],
sp.*
FROM Employee sp
INNER JOIN
CONTAINSTABLE(Employee, *, 'John OR Hamburg', 1000) AS keyTblSp
ON sp.EmployeeId = keyTblSp.[KEY]
UNION ALL
SELECT
(keyTbl.RANK * 2) AS [Rank],
sp.*
FROM Employee sp
LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId
INNER JOIN
CONTAINSTABLE([Address], *, 'John OR Hamburg', 1000) AS keyTbl
ON addr.AddressId = keyTbl.[KEY]
UNION ALL
SELECT
(keyTbl.RANK * 2) AS [Rank],
sp.*
FROM Employee sp
LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId
LEFT OUTER JOIN [City] cty ON cty.CityId = addr.CityId
INNER JOIN
CONTAINSTABLE([City], *, 'John OR Hamburg', 1000) AS keyTbl
ON cty.CityId = keyTbl.[KEY]
这导致不仅是居住在汉堡的约翰被送回,而且每个叫约翰的人和每个居住在汉堡的人都被送回。
我能想到的一个解决方案是,以某种方式计算Employee表中的一列,该列包含全文搜索所需的所有值,如
员工表
EmployeeId、Firstname、Lastname、FulltextColumn
样本数据
1 |约翰|米勒|约翰·米勒大道12号汉堡22335
这样我就可以做了
SELECT
(keyTbl.RANK) AS [Rank],
sp.*
FROM Employee sp
INNER JOIN
CONTAINSTABLE([Employee], FulltextColumn, 'John AND Hamburg', 1000) AS keyTbl
ON sp.EmployeeId = keyTbl.[KEY]
这可能吗?还有其他想法吗?您可以使用连接要求地址和人名都匹配
SELECT
(keyTblSp.RANK * 3) AS [Rank],
sp.*
FROM Employee sp
INNER JOIN
CONTAINSTABLE(Employee, *, 'John OR Hamburg', 1000) AS keyTblSp
ON sp.EmployeeId = keyTblSp.[KEY]
join
(
SELECT
(keyTbl.RANK * 2) AS [Rank],
sp.*
FROM Employee sp
LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId
INNER JOIN
CONTAINSTABLE([Address], *, 'John OR Hamburg', 1000) AS keyTbl
ON addr.AddressId = keyTbl.[KEY]
UNION ALL
SELECT
(keyTbl.RANK * 2) AS [Rank],
sp.*
FROM Employee sp
LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId
LEFT OUTER JOIN [City] cty ON cty.CityId = addr.CityId
INNER JOIN
CONTAINSTABLE([City], *, 'John OR Hamburg', 1000) AS keyTbl
ON cty.CityId = keyTbl.[KEY]
) addr_matches
on addr_matches.EmployeeId = sp.EmployeeId
我想这会给你你指定的结果,显然,这需要一个名称和地址搜索词,搜索才能返回任何结果。你没有指定如果有人只是搜索“John”会发生什么,如果你总是能同时得到姓名和地址,我想上面的方法会很好 您可以使用连接来要求地址和人名都匹配
SELECT
(keyTblSp.RANK * 3) AS [Rank],
sp.*
FROM Employee sp
INNER JOIN
CONTAINSTABLE(Employee, *, 'John OR Hamburg', 1000) AS keyTblSp
ON sp.EmployeeId = keyTblSp.[KEY]
join
(
SELECT
(keyTbl.RANK * 2) AS [Rank],
sp.*
FROM Employee sp
LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId
INNER JOIN
CONTAINSTABLE([Address], *, 'John OR Hamburg', 1000) AS keyTbl
ON addr.AddressId = keyTbl.[KEY]
UNION ALL
SELECT
(keyTbl.RANK * 2) AS [Rank],
sp.*
FROM Employee sp
LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId
LEFT OUTER JOIN [City] cty ON cty.CityId = addr.CityId
INNER JOIN
CONTAINSTABLE([City], *, 'John OR Hamburg', 1000) AS keyTbl
ON cty.CityId = keyTbl.[KEY]
) addr_matches
on addr_matches.EmployeeId = sp.EmployeeId
我想这会给你你指定的结果,显然,这需要一个名称和地址搜索词,搜索才能返回任何结果。你没有指定如果有人只是搜索“John”会发生什么,如果你总是能同时得到姓名和地址,我想上面的方法会很好 我认为计算列是您最好的选择。它将是最灵活的,因为您不知道搜索查询中将包含哪些令牌,它将执行得更好,并且您的存储过程将更小 为了基于另一个表中的数据创建计算列,必须使用UDF(用户定义函数)创建它,如下所示:
CREATE FUNCTION dbo.udf_ComputedColumnFunction (
@EmployeeId INT
)
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @RET VARCHAR(1000)
SELECT
@RET = e.FirstName + ' ' + e.LastName + ' ' + a.Street + ' ' + a.StreetNumber + ' ' + c.Name + ' ' + c.ZipCode
FROM Employee e
INNER JOIN Address a ON a.EmployeeId = e.EmployeeId
INNER JOIN City c ON c.CityId = a.CityId
RETURN @RET
END
GO
ALTER TABLE Employee
ADD SearchColumn AS dbo.udf_ComputedColumnFunction(EmployeeId)
如果您不想这样做,您可以:
- 创建并添加全文索引
- 创建由触发器或定期运行存储过程填充的查找表
CREATE FUNCTION dbo.udf_ComputedColumnFunction (
@EmployeeId INT
)
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @RET VARCHAR(1000)
SELECT
@RET = e.FirstName + ' ' + e.LastName + ' ' + a.Street + ' ' + a.StreetNumber + ' ' + c.Name + ' ' + c.ZipCode
FROM Employee e
INNER JOIN Address a ON a.EmployeeId = e.EmployeeId
INNER JOIN City c ON c.CityId = a.CityId
RETURN @RET
END
GO
ALTER TABLE Employee
ADD SearchColumn AS dbo.udf_ComputedColumnFunction(EmployeeId)
如果您不想这样做,您可以:
- 创建并添加全文索引
- 创建由触发器或定期运行存储过程填充的查找表
如果您只想选择“或”,那么使用FreeTextTable,就好像默认情况下同时应用同义词库和屈折形式一样。我认为您应该创建和索引视图,并且应该通过用空格或破折号分隔,将可用于全文的所有列合并到一个列中,因为它们都是sql server 2005的噪音词。然后在该索引视图上创建全文索引 Contains表默认情况下不应用词形变化或同义词表的形式。这两个是很好的配置和使用选项
如果您只想选择“或”,请使用FreeTextTable,就像默认情况下同时应用同义词库和词形变化表一样。您好,谢谢您的建议。我知道有一个特殊的表格,在一列中包含所有必需的信息。存储过程用于通过使用每个参与表的触发器来更新索引。全文目录用于新表以执行快速搜索。您好,谢谢您的建议。我知道有一个特殊的表格,在一列中包含所有必需的信息。存储过程用于通过使用每个参与表的触发器来更新索引。全文目录用于新表以执行快速搜索。