2016-10-24 5 views
0
  • Ich habe eine MySQL-Tabelle, die Fragen für Benutzer enthält.
    • Jedem Benutzer ist eine Kategorie zugewiesen.
    • Jede Frage kann auf eine oder mehrere Benutzerkategorien ausgerichtet sein.
    • Die Kategorie der Frage befindet sich in einer Spalte in der Fragetabelle und nicht in einer separaten Tabelle.
    • Für Fragen, die mehrere Benutzergruppen zielen, wird jede Kategorie durch ein Zeichen wie |

vom Tisch zu bekommen alle Fragen getrennt werden, in denen ein bestimmten Benutzer Kategorie paßt Ich versuche, dass der Zeichenfolge, die sich in der Kategorie-Spalte für eine Frage befindet.Passende Wörter in Zeichenfolge

Ich habe in ein paar Probleme lief:

$string^ wird nicht funktionieren, da die Zeichenfolge ich mit vergleichen bin versucht, etwas sein kann, wie Retail|Field Based

ich keine WHERE category LIKE "%'.$category.'%" weil einige Kategorien verwenden können teilen Wörter. Zum Beispiel: Retail und Retail Roadshow Wenn Retail die Kategorie war, würde es paßt auch auf Retail Roadshow

ich etwas bin ratlos, wie dies zu tun mit der aktuellen Datenbankstruktur. Ich plane nicht, die Struktur der Datenbank zu ändern, aber möglicherweise, wenn ich nicht eine funktionierende Antwort bekommen kann, wie es zurzeit funktioniert.

+3

Ihr Instinkt ist korrekt, eine MySQL-Tabelle sollte keine Art von Begrenzungsdaten enthalten, jeder Wert sollte in einer eigenen Zeile in einer anderen Tabelle vorhanden sein e. Befolgen Sie diesen Grundsatz und viele der Probleme, die Sie am Rande der Begegnung haben, werden verschwinden. –

+2

Wenn Sie den Pipe Delimeter '|' behalten möchten, können Sie '$ sql =" select * von Ihrer_Tabelle wählen, wobei Kategorie = '$ Kategorie' oder Kategorie wie '$ Kategorie |%' oder Kategorie LIKE '% | $ Kategorie |% 'oder Kategorie wie'% | $ category '";' – MonkeyZeus

+0

Was passiert, wenn eine Benutzerkategorie tatsächlich eine Pipe im Kategorienamen hat? – MonkeyZeus

Antwort

0

Wie bereits erwähnt, funktionieren Datenbanken am besten mit Tabellen.

Aber um des Arguments willen sehen wir, wie wir Ihr Ziel ohne DB-Refaktor erreichen können.

Zuerst müssen Sie alle Ihre Rohre durch Kommas ersetzen.

replace(column, '|', ',') 

nun auf die Ergebnisse verwenden FIND_IN_SET:

find_in_set('Retail', replace(column, '|', ',')) 

MySQL Indizes mit 1 beginnen, so dass Sie überprüfen können, ob Rrtail mit in Spalte vorhanden:

find_in_set('Retail', replace(column, '|', ',')) > 0 
2

Sie haben drei Möglichkeiten:

1) teilen Sie die Wildcard-Matching in ein pro-Wort-Geschäft:

foo LIKE '%bar baz%' ->foo LIKE '%bar%' AND foo LIKE '%baz%'

2) Verwenden Sie einen Volltextindex

foo like '%bar baz%' ->MATCH(foo AGAINST 'bar baz')

3) Oder normalisieren Tisch, so dass jedes Keyword ein eigenes Kind Datensatz ist:

JOIN keywords ON ... 
WHERE keywords.word IN ('bar', 'baz') 
+0

Die Normalisierungsoption ist wahrscheinlich die beste Leistung hier. 'LIKE' ist notorisch langsam. – tadman

+0

nein. es ist nicht "wie" selbst. es ist das ankerlose Wildcarding. '% foo%' ist langsam, weil der Index nicht verwendet werden kann. 'foo%' kann (allgemein) Indizes verwenden. und 'wie 'foo'' ist sowieso gleichbedeutend mit' field = 'boo'. –

+0

Richtig, aber 'LIKE' ohne Anker ist ziemlich sinnlos. – tadman

Verwandte Themen