2008-10-15 7 views
5

J'ai un catalogue de texte complet avec deux tables. La table A a 4 colonnes (a1, a2, a3, a4) dont 3 sont indexées dans le catalogue, a2, a3, a4. a1 est la clé primaire.Comment utiliser la recherche en texte intégral sur plusieurs tables, SQL Server 2005

La table B a 3 colonnes (b1, b2, b3, b4), dont deux sont indexées dans le catalogue, b3 et b4. b1 est le PK de cette table, b2 est le FK à tableA.

Je veux faire quelque chose comme

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] 

Mais cela ne fonctionne pas ... je peux obtenir une seule table pour travailler, par exemple.

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] 

mais jamais plus d'un tableau.

Est-ce que quelqu'un peut donner une explication et/ou un exemple des étapes nécessaires à la recherche en texte intégral sur plusieurs tables.

Répondre

2

Je ne suis pas certain d'avoir compris ce que vous essayiez de faire. J'ai interprété votre question comme si vous vouliez renvoyer tous les éléments du tableau A correspondant au terme recherché. De plus, vous vouliez additionner le rang de l'élément de la TableA plus les éléments correspondants de la TableB.

La meilleure façon de le faire est d'utiliser une variable de table avec 3 requêtes.

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 

Ce n'est pas aussi élégant que l'utilisation d'une requête, mais il devrait être facile à suivre et vous permet de décider si oui ou non d'inclure les enregistrements dans la 3ème requête.

4

Votre requête ne renvoie que les enregistrements si A et B contiennent le texte recherché.

Vous ne dites pas ce qui ne marche pas, cependant.

Pourquoi ne pas LEFT OUTER JOIN les recherches en texte intégral et remplacer:

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

et

WHERE ftTableA.Key IS NOT NULL OR ftTableB.Key IS NOT NULL