Как использовать полнотекстовый поиск по нескольким таблицам, SQL Server 2005 - PullRequest
5 голосов
/ 15 октября 2008

У меня есть полнотекстовый каталог с двумя таблицами в нем.

Таблица A имеет 4 столбца (a1, a2, a3, a4), которые 3 проиндексированы в каталоге, a2, a3, a4. a1 - это первичный ключ.

ТаблицаB имеет 3 столбца (b1, b2, b3, b4), два из которых проиндексированы в каталоге, b3 и b4. b1 - это PK этой таблицы, b2 - это FK для таблицы A.

Я хочу сделать что-то вроде

SELECT *, (ftTableA.[RANK] + ftTableB.[RANK]) AS total_rank 
FROM tableA
INNER JOIN tableB ON tableA.a1=tableB.b2
INNER JOIN FREETEXTTABLE(tableA, (a2,a3,a4), 'search term') as ftTableA ON tableA.a1=ftTableA.[KEY]
INNER JOIN FREETEXTTABLE(tableB, (b3,b4), 'search term') as ftTableB ON tableB.11=ftTableB.[KEY]

Но это не работает ... Я могу заставить работать одну таблицу, например.

SELECT *, (ftTableA.[RANK] + ftTableB.[RANK]) AS total_rank 
FROM tableA
INNER JOIN FREETEXTTABLE(tableA, (a2,a3,a4), 'search term') as ftTableA ON tableA.a1=ftTableA.[KEY]

но не более одного стола.

Может ли кто-нибудь дать объяснение и / или пример шагов, необходимых для полнотекстового поиска по нескольким таблицам.

Ответы [ 2 ]

4 голосов
/ 16 октября 2008

Ваш запрос возвращает записи, только если A и связанный с ним B содержит текст поиска.

Вы не утверждаете, что не работает, хотя.

Почему бы ЛЕВУЮ ВНЕШНЮЮ СТАНЦИЮ не искать и заменить:

SELECT *, (ISNULL(ftTableA.[RANK], 0) + ISNULL(ftTableB.[RANK], 0)) AS total_rank 

и

WHERE ftTableA.Key IS NOT NULL OR ftTableB.Key IS NOT NULL
2 голосов
/ 16 октября 2008

Я не уверен, что понял, что ты пытался сделать. Я интерпретировал ваш вопрос так, как будто вы хотите вернуть все элементы таблицы А, которые соответствуют поисковому запросу. Кроме того, вы хотели бы суммировать ранг от элемента в Таблице A плюс соответствующие элементы в Таблице B.

Лучший способ сделать это - использовать переменную таблицы с 3 запросами.

DECLARE @Results Table (a1 Int UNIQUE, Rank Int)

--Insert into @Results all matching items from TableA
INSERT INTO @Results
(a1, Rank)
( SELECT TableA.a1, FT.Rank
FROM TableA INNER JOIN FreeTextTable(TableA, *, 'search term') FT
ON TableA.A1 = FT.[Key]
)

--Update all of the ranks in @Results with a sum of current value plus the sum of
--all sub items (in TableB)
UPDATE @Results
SET Rank = RS.Rank + FT.Rank
FROM @Results RS INNER JOIN TableB
ON RS.A1 = TableB.b2
INNER JOIN FreeTextTable(TableB, *, 'search term') FT
ON TableB.b1 = FT.[Key]

--Now insert into @Results any items that has a match in TableB but not in TableA
--This query may/may not be desired based on your business rules.
INSERT INTO @Results
(SkillKeyId, Rank)
( SELECT TableB.b2, Sum(FT.Rank)
FROM TableB INNER JOIN FreeTextTable(TableB, *, 'search term') FT
ON TableB.b1 = FT.[key]
LEFT JOIN @Results RS
ON RS.a1 = TableB.b2
WHERE RS.a1 IS NULL
GROUP BY TableB.b2
)

--All that's left is to return the results
SELECT TableA.*, RS.Rank AS Total_Rank
FROM TableA INNER JOIN @Results RS
ON TableA.a1 = RS.a1
ORDER BY RS.Rank DESC

Это не так элегантно, как использование одного запроса, но за ним должно быть легко следить, и вы можете решить, включать ли записи в третий запрос.

...