Frage

Kann/sollte ich beim Erstellen einer gespeicherten Prozedur/Abfrage ein LIKE-Kriterium als Teil eines INNER JOIN verwenden?Ich bin mir nicht sicher, ob ich das Richtige frage, also lassen Sie es mich erklären.

Ich erstelle eine Prozedur, die eine Liste von Schlüsselwörtern benötigt, nach denen in einer Spalte gesucht werden soll, die Text enthält.Wenn ich an der Konsole säße, würde ich es so ausführen:

SELECT Id, Name, Description
  FROM dbo.Card
 WHERE Description LIKE '%warrior%' 
       OR
       Description LIKE '%fiend%' 
       OR 
       Description LIKE '%damage%'

Aber ein Trick, den ich vor einiger Zeit gelernt habe, um „stark typisierte“ Listen in einer gespeicherten Prozedur zu analysieren, besteht darin, die Liste in eine Tabellenvariable/temporäre Tabelle zu analysieren, sie in den richtigen Typ zu konvertieren und dann einen INNER JOIN für diese Tabelle auszuführen in meinem endgültigen Ergebnissatz.Dies funktioniert hervorragend, wenn Sie beispielsweise eine Liste ganzzahliger IDs an die Prozedur senden.Am Ende habe ich eine letzte Abfrage, die so aussieht:

SELECT Id, Name, Description
  FROM dbo.Card
       INNER JOIN @tblExclusiveCard ON dbo.Card.Id = @tblExclusiveCard.CardId

Ich möchte diesen Trick mit einer Liste von Zeichenfolgen verwenden.Da ich aber nach einem bestimmten Schlüsselwort suche, verwende ich die LIKE-Klausel.Im Idealfall würde meine letzte Abfrage also so aussehen:

SELECT Id, Name, Description
  FROM dbo.Card
       INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' + @tblKeyword.Value + '%'

Ist das möglich/empfehlenswert?

Gibt es einen besseren Weg, so etwas zu tun?


Der Grund, warum ich Platzhalter an beiden Enden der Klausel einfüge, liegt darin, dass in den Kartentexten Begriffe wie „Erzunterweltler“, „Tierkrieger“, „direkter Schaden“ und „Kampfschaden“ verwendet werden.

Ich habe den Eindruck, dass ich je nach Leistung entweder die von mir angegebene Abfrage oder eine Volltext-Stichwortsuche verwenden kann, um dieselbe Aufgabe zu erfüllen?

Gibt es noch etwas, was ich tun muss, außer dass der Server einen Textindex für die Felder erstellt, nach denen ich eine Textsuche durchführen möchte?

War es hilfreich?

Lösung

Ihre erste Abfrage funktioniert, erfordert jedoch einen vollständigen Tabellenscan, da alle Indizes für diese Spalte ignoriert werden.Sie müssen außerdem dynamisches SQL ausführen, um alle Ihre LIKE-Klauseln zu generieren.

Versuchen Sie eine Volltextsuche, wenn Sie SQL Server verwenden, oder sehen Sie sich eines davon an Lucene Implementierungen.Joel hat kürzlich über seinen Erfolg damit gesprochen.

Andere Tipps

Versuche dies

    select * from Table_1 a
    left join Table_2 b on b.type LIKE '%' + a.type + '%'

Diese Praxis ist nicht ideal.Mit Vorsicht verwenden.

Anscheinend suchen Sie nach einer Volltextsuche.Weil Sie eine Reihe von Schlüsselwörtern anhand der Kartenbeschreibung abfragen und Treffer finden möchten?Richtig?

Ich persönlich habe es schon einmal gemacht und es hat bei mir gut geklappt.Die einzigen Probleme, die ich sehen konnte, sind möglicherweise Probleme mit einer nicht indizierten Spalte, aber ich denke, Sie hätten das gleiche Problem mit einer where-Klausel.

Mein Rat an Sie ist, sich einfach die Ausführungspläne zwischen den beiden anzusehen.Ich bin mir sicher, dass es je nach Situation unterschiedlich sein wird, welches besser ist, genau wie bei allen guten Programmierproblemen.

@Dillie-O
Wie groß ist dieser Tisch?
Welchen Datentyp hat das Beschreibungsfeld?

Wenn beides klein ist, wäre eine Volltextsuche übertrieben.

@Dillie-O
Vielleicht nicht die Antwort, nach der Sie gesucht haben, aber ich würde eine Schemaänderung befürworten ...

vorgeschlagenes Schema:

create table name(
    nameID identity / int
   ,name varchar(50))

create table description(
    descID identity / int
   ,desc varchar(50)) --something reasonable and to make the most of it alwase lower case your values

create table nameDescJunc(
    nameID  int
    ,descID int)

Dadurch können Sie Indizes verwenden, ohne eine Zusatzlösung implementieren zu müssen, und Ihre Daten bleiben atomar.

verwandt: Empfohlenes SQL-Datenbankdesign für Tags oder Tagging

Ein Trick, den ich ein wenig aufgenommen habe, um eine "stark tippte" Liste in einem gespeicherten Verfahren zu machen, besteht darin, die Liste in eine Tabellenvariable/temporäre Tabelle zu analysieren

Ich denke, was Sie hier meinen könnten, ist, die einzuschließenden Schlüsselwörter in eine Tabelle einzufügen und sie dann zu verwenden relationale Aufteilung um Übereinstimmungen zu finden (könnte auch eine andere Tabelle für auszuschließende Wörter verwenden).Ein ausgearbeitetes Beispiel in SQL finden Sie unter Stichwortsuche von Joe Celko.

Versuch es...

select * from table11 a inner join  table2 b on b.id like (select '%'+a.id+'%') where a.city='abc'.

Bei mir funktioniert es. :-)

Die Leistung hängt vom tatsächlichen Server ab, den Sie verwenden, sowie vom Schema der Daten und der Datenmenge.Mit aktuellen Versionen von MS SQL Server sollte diese Abfrage einwandfrei funktionieren (MS SQL Server 7.0 hatte Probleme mit dieser Syntax, aber es wurde in SP2 behoben).

Haben Sie diesen Code über einen Profiler ausgeführt?Wenn die Leistung schnell genug ist und die Daten über die entsprechenden Indizes verfügen, sollten Sie bereit sein.

LIKE '%fiend%' wird niemals eine Suche verwenden, LIKE 'fiend%' schon.Eine einfache Suche mit Platzhaltern ist nicht möglich

Versuche dies;

SELECT Id, Name, Description
FROM dbo.Card
INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' + 
                                CONCAT(CONCAT('%',@tblKeyword.Value),'%') + '%'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top