我有以下内容的表:推荐的方法来搜索分层数据MSSQL2008
- 类别ID
- PARENTID
- 名称
我想有一个搜索功能,可能会搜索整个层次结构,例如,这是一个类别的面包屑:
摩托车/ J apan /川崎/ 600cc到800cc/1998-2004
如果有人搜索“600cc川崎”,我希望返回上述类别。所以应该返回匹配最多的类别路径。
目前,我想出了这一点:
IF ISNULL(@searchTerm, '') = ''
SET @searchTerm = '""'
DECLARE @Result TABLE (CategoryId int)
DECLARE CategoryCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT CategoryId, ParentId, Name
FROM Category
WHERE FREETEXT([Name], @searchTerm)
OPEN CategoryCursor
DECLARE @CategoryId int
DECLARE @ParentId int
DECLARE @Name nvarchar(100)
FETCH NEXT FROM CategoryCursor INTO @CategoryId, @ParentId, @Name
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @FullPath nvarchar(1000)
SET @FullPath = @Name
WHILE @ParentId <> 0
BEGIN
SELECT @ParentId = ParentId, @Name = [Name]
FROM Category
WHERE CategoryId = @ParentId
SET @FullPath = @Name + '\' + @FullPath
END
-- Check if @FullPath contains all of the searchterms
DECLARE @found bit
DECLARE @searchWords NVARCHAR(100)
DECLARE @searchText NVARCHAR(255)
DECLARE @pos int
SET @found = 1
SET @searchWords = @searchTerm + ' '
SET @pos = CHARINDEX(' ', @searchWords)
WHILE @pos <> 0
BEGIN
SET @searchText = LEFT(@searchWords, @pos - 1)
SET @searchWords = STUFF(@searchWords, 1, @pos, '')
SET @pos = CHARINDEX(' ', @searchWords)
IF @searchText = '' CONTINUE
IF @FullPath NOT LIKE '%' + @searchText + '%'
BEGIN
SET @found = 0
BREAK
END
END
IF @found = 1
INSERT INTO @Result VALUES(@CategoryId)
FETCH NEXT FROM CategoryCursor INTO @CategoryId, @ParentId, @Name
END
CLOSE CategoryCursor
DEALLOCATE CategoryCursor
SELECT *
FROM Category
WHERE categoryID IN (SELECT categoryId FROM @Result)
这将首先发现其含有任何searchwords的所有catagorynames。问题是,我不想让其他品牌的“600cc”返回,只有与“川崎”有关的那个。 接下来,我为当前类别构建面包屑并查看它是否包含所有搜索词。
它的工作原理,但我认为这是无效的,所以我正在寻找一个更好的方法。
也许作为文本存储在一个新的列中的完整路径和搜索?
许多有用的参考文献[这里] [1]。 [1]:http://stackoverflow.com/questions/4048151/what-are-the-options-for-storing-hierarchical-data-in-a-relational-database – TMS