2009-05-29 10 views
0

J'ai besoin d'aide pour concevoir une requête qui sera utilisée pour renvoyer les résultats de recherche d'un site Web. Les utilisateurs effectuent une recherche en sélectionnant des éléments dans une liste d'attributs. Chaque élément de résultat de recherche renvoyé doit avoir TOUS les attributs sélectionnés par l'utilisateur. Le défi (pour moi au moins!) Est de savoir comment ne retourner que les résultats qui ont TOUS les attributs par rapport à QUELCONQUE d'entre eux.Requête SQL pour la récupération des résultats de recherche

Les éléments de résultat de recherche (appelons-les WIDGET) se trouvent dans la table WIDGET. Les attributs de widget possibles sont dans la table ATTRIBUTE. Une table de jonction (WIDGETATTRIBUTEJUNCTION) stocke les attributs réels 0,1..n pour chaque WIDGET.

Je n'arrive pas à comprendre une requête qui, une fois fournie une liste d'attributs de widget, retournera des lignes qui ont chacun de ces attributs. Je pense que je pourrais utiliser une sous-requête ALL et/ou un INTERSECT mais je ne sais pas comment.

Répondre

1

Vous pouvez utiliser quelque chose de similaire à ce qui suit,

SELECT WidgetID FROM Widget INNER JOIN WidgetAttributes WA ON WA.Key = SearchAttributes.Key AND WA.WidgetID = Widget.WidgetID GROUP BY WidgetID HAVING COUNT(Widget.WidgetID) > @SearchAttributesCount 

La clé étant le GROUP BY AYANT qui limite à seulement inclure toutes les lignes Widget qui correspondent à tous les attributs.

0

Si seulement des tableaux SQL ... pris en charge

Il y a deux façons vous pouvez aller à ce sujet, ma méthode préférée consiste à envoyer une chaîne (contenant l'ID attribut) à SQL puis diviser la chaîne en table.

Quelque chose comme:

create function dbo.fn_makeArray (@value nvarchar(max)) 
    returns @table table([key] nvarchar(256)) 
    begin 
     declare @start int; 
     declare @end int; 

     select @start = 1, @end = charindex(',', @value); 

     while (@start < len(@value) + 1) 
     begin 
      if (@end = 0) 
       set @end = len(@value) + 1; 

      insert into @table ([key]) 
      values(substring(@value, @start, @end - @start)); 

      set @start = @end + 1; 
      set @end = charindex(',', @value, @start); 
     end 
     return; 
    end 
0

Nous avons eu un problème comme celui-ci un certain temps:

select WidgetName,AttributeName 
from Widgets 
left join WALinks on WALinks.wid = WidgetID 
left join Attributes on WALinks.aid = AttributeID 

where WidgetID in 
(
    select wId 
    from waLinks 
    where aid in (1,3) 
    group by wId 
    having count(aId) = 2 
) 

Vous pouvez alors définir les attributs à la liste « dans (1,3) » et toujours Ajustez le nombre de la requête de comptage au nombre d'attributs que vous recherchez.

Questions connexes