我有以下內容的表:推薦的方法來搜索分層數據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