2 Stimmen

SQL-Text-Suche, AND-Bestellung

Ich habe eine Frage:

SELECT *
FROM Items
WHERE column LIKE '%foo%'
   OR column LIKE '%bar%'

Wie kann ich die Ergebnisse bestellen?

Angenommen, ich habe Zeilen, die mit "foo" übereinstimmen, und Zeilen, die mit "bar" übereinstimmen, aber ich habe auch eine Zeile mit "foobar".

Wie ordne ich die zurückgegebenen Zeilen so an, dass die ersten Ergebnisse diejenigen sind, die mehr LIKEs gefunden haben?

0voto

Booji Boy Punkte 4419

Probieren Sie diesen Code aus:

SELECT * FROM Items WHERE column LIKE '%foo%' OR column LIKE '%bar%'
order by (select count(*) from items i where i.column= item.column) DESC 

Sie können auch gruppieren nach column y count(*) dann ORDER wenn Sie sich nicht für die Details interessieren.

0voto

Mike Tunnicliffe Punkte 10404

Versuchen Sie es doch einmal damit:

SELECT *
FROM Items
WHERE column LIKE '%foo%' OR column LIKE '%bar%'
ORDER BY CASE WHEN column LIKE '%foo%' AND column LIKE '%bar%' THEN 1 ELSE 0 END DESC

Hinweis: Dies ist trocken kodiert und wahrscheinlich nicht sehr portabel.

0voto

Jolyon Punkte 185

2 Abfragen:

SELECT * FROM Items WHERE column LIKE '%foo%' AND column LIKE '%bar%';
SELECT * FROM Items WHERE (column LIKE '%foo%' AND column NOT LIKE '%bar%') OR (column NOT LIKE '%foo%' AND LIKE '%bar%')

(Kein XOR in SQL)

0voto

Mark Nold Punkte 5482

Nicht alle RDBMS unterstützen IF (oder DECODE in Oracle) Anweisungen. Falls nicht, könnten Sie eine Unterabfrage verwenden, um die Tabelle "a" zu definieren und nach allen Mitarbeitern mit dem Namen JO SMITH oder einer Kombination zu suchen.

SELECT 
 a.employee_id,
 a.surname,
 sum(a.counter)
FROM

 (SELECT
   employee_id,
   surname,
   1 as counter
  FROM
   MyTable
  WHERE
   surname like '%SMITH%'

  UNION ALL

  SELECT
   employee_id,
   surname,
   1 as counter
  FROM
   MyTable
  WHERE
   surname like '%JO%'
   ) a

GROUP BY 
 a.employee_id,
 a.surname
ORDER BY 3,1,2

Achten Sie darauf, dass Sie UNION ALL verwenden, sonst wird es nicht funktionieren. Sie können auch UPPER() verwenden, um Ihre Suche nicht von Groß- und Kleinschreibung abhängig zu machen.

0voto

Matt Punkte 4942

So wie Ihre Abfrage derzeit geschrieben ist, liefert die WHERE-Klausel keine Informationen, die zum Sortieren der Ergebnisse verwendet werden können. Ich mag Brians Idee ; fügen Sie eine konstante Spalte hinzu und UNION die Abfragen und Sie könnten sogar alles in einer Ergebnismenge erhalten. Zum Beispiel:

SELECT 1 as rank, * FROM Items WHERE column LIKE '%foo%' AND column LIKE '%bar%'
UNION
SELECT 2 as rank, * FROM Items WHERE column LIKE '%foo%' AND column NOT LIKE '%bar%'
UNION
SELECT 2 as rank, * FROM Items WHERE column LIKE '%bar%' AND column NOT LIKE '%foo%'
ORDER BY rank

Dies würde jedoch nur zu folgendem Ergebnis führen:

  • Die ungeordnete Menge aller Zeilen, die mit foo und bar übereinstimmen
  • gefolgt von (der ungeordneten Menge von) allen Zeilen, die mit foo oder bar übereinstimmen, aber nicht mit beiden (obwohl Sie diese in zwei separate Gruppen aufteilen könnten, indem Sie eine andere Konstante in der letzten SELECT-Anweisung verwenden).

Das könnte genau das sein, wonach Sie suchen, aber es würde Ihnen nicht sagen, welche Zeilen dreimal mit foo übereinstimmen, oder sie vor den Zeilen sortieren, die nur eine Instanz von foo enthalten. Außerdem können all diese LIKEs teuer werden. Wenn Sie die Ergebnisse wirklich nach Relevanz sortieren wollen (wie auch immer Sie das definieren), sollten Sie vielleicht besser einen Volltextindex verwenden. Wenn Sie MS SQL Server verwenden, verfügt dieser über einen eingebauten Dienst, der dies ermöglicht, und es gibt auch Produkte von Drittanbietern, die dasselbe tun.

EDIT: Nachdem ich mir alle anderen Antworten angesehen habe (es waren nur zwei als ich mit meiner angefangen habe - ich muss offensichtlich lernen, schneller zu denken ;-) ), ist es offensichtlich, dass es mehrere Möglichkeiten gibt, dies zu tun, je nachdem, was genau Sie erreichen wollen. Ich würde Ihnen raten, Lösungen zu testen und zu vergleichen, je nachdem, wie sie funktionieren in Ihrem System . Ich bin kein Leistungs-/Tuning-Experte, aber Funktionen neigen dazu, die Dinge zu verlangsamen, vor allem, wenn man nach dem Ergebnis einer Funktion sortiert. Der LIKE-Operator ist auch nicht unbedingt flink. Als Entwickler scheint es natürlich zu sein, vertraute Konstrukte wie "IF" und "CASE" zu verwenden, aber Abfragen, die eher einen mengenbasierten Ansatz verwenden, haben normalerweise eine bessere Leistung in einem RDMS. Auch hier gilt: YMMV, also testen Sie am besten, wenn Sie sich um die Leistung sorgen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X