2009-05-29 5 views
0

Ich brauche Hilfe beim Entwerfen einer Abfrage, die verwendet wird, um die Suchergebnisse einer Website zurückzugeben. Benutzer suchen, indem sie Elemente aus einer Liste von Attributen auswählen. Jedes zurückgegebene Suchergebniselement muss ALLE vom Benutzer ausgewählten Attribute aufweisen.SQL-Abfrage zum Abrufen von Suchergebnissen

Die Herausforderung (für mich mindestens!) Ist herauszufinden, wie nur Ergebnisse zurückgegeben werden, die ALLE Attribute im Vergleich zu nur einer von ihnen haben.

Die Suchergebniselemente (wir nennen sie WIDGETs) befinden sich in der WIDGET-Tabelle. Mögliche Widgetattribute befinden sich in der ATTRIBUTE-Tabelle. Eine Junction-Tabelle (WIDGETATTRIBUTEJUNCTION) speichert die 0,1..n tatsächlichen Attribute für jeden WIDGET.

Ich kann eine Abfrage nicht herausfinden, die, wenn eine Liste von Widget-Attributen geliefert wird, Zeilen zurückgibt, die jedes dieser Attribute haben. Ich vermute, ich könnte eine ALL-Unterabfrage und/oder eine INTERSECT verwenden, aber nicht sicher, wie.

Antwort

1

Sie etwas ähnlich der folgenden verwenden könnte,

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 

Der Schlüssel der Gruppe, die BY-Anweisung, die es nur begrenzt sind alle Widget Zeilen, die alle Attribute entsprechen.

0

Wenn nur SQL unterstützt Arrays ...

Es gibt ein paar Möglichkeiten, wie Sie zu diesem gehen können, meine bevorzugte Methode ist eine Zeichenkette (mit dem Attribut-IDs) senden dann die Zeichenfolge in einen spalt SQL Tabelle.

Etwas wie:

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

Wir hatten ein Problem wie dieses eine Weile zurück:

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 
) 

Anschließend können Sie die Attribute in die Liste "in (1,3)" gesetzt und immer Passen Sie die Anzahl für die Zählungsabfrage an die Anzahl der übereinstimmenden Attribute an.