2017-07-20 7 views
-4

Ich bin mir der LIKE Funktion in SQL bewusst, aber ich muss etwas etwas komplexer tun.mySQL mehr Präzision mit LIKE-Funktion

In meiner Tabelle people habe ich ein Textfeld namens banned, die eine Zeichenfolge aller verbotenen Namen getrennt mit einem @ speichert. Also lassen Sie uns banned = [email protected]@Billy

sagen, dass ich überprüfen möchten, ob der Name Bob

erscheint
SELECT * FROM people WHERE banned LIKE '%$Bob%' 

Dies würde vermutlich Ergebnisse finden wegen der Bobjob in der Zeichenkette.

Gibt es eine Möglichkeit, ich kann es so machen, dass es nur vollständige Namen innerhalb der @ Trennzeichen findet?

+7

Warum sind alle Ihre gebannten Benutzer speichert in 1 String? Es sei denn, ich verpasse etwas. Das ist nur eine schlechte Struktur – GrumpyCrouton

+0

Es ist nicht wirklich für die gesperrten Benutzer, es ist für eine Funktion auf meiner Website, wo nur 2 oder 3 Namen jemals verwendet werden würde, habe ich einfach für einfachere Erklärung verboten verwendet – user1022585

+1

Klingt wie ein [XY-Problem] (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) zu mir. – GrumpyCrouton

Antwort

2

Vergessen Sie in einer dieser beiden mit index .... aber da Sie% var% verwenden ich Sie gehe davon aus das schon erwartet.

Wir könnten ein @ am Anfang und Ende von gebannt, so dass jeder Name von @ umgeben ist dann verwenden Sie die @ im Namen suchen. (Erwartet, dass kein Name @ drin haben .... und erwartet nicht verboten beginnen noch mit einem @ enden (und wenn sie es tun es wirklich nicht auf die unten Materie))

Where concat('@', banned,'@') like '%@[email protected]%'

Verwenden finde in set, indem du @ in a umwandelst, und wenn das Ergebnis> 1 ist, wurde es gefunden.

find_in_set('Bob',replace(banned,','))>1

1

Sie sollten mit vars wie Bedingung eine richtige concat für Build verwenden und @

SELECT * FROM people WHERE banned LIKE concat('%@%', '$Bob','%@%') 
+0

@GrumpyCrouton Antwort aktualisiert .. – scaisEdge

+0

würde Bob zurückgegeben werden, wenn gebannt enthalten bob @ sam @ Smith oder sam @ Smith @ Bob? Wirklich müssen Sie das @ auf das Verbot setzen und suchen. – xQbert

+0

NEIN ... sollte nur zurückgegeben werden wenn @ bob @ wie von OP angefordert – scaisEdge

1

Das ist keine ideale Datenstruktur ist, sondern dass für den Moment beiseite zu verlassen:

Wenn Sie das Trennzeichen ein Komma ändern kann, mysql eine integrierte Funktion für die hat: FIND_IN_SET

SELECT * FROM people WHERE FIND_IN_SET('Bob', list); 

Andernfalls können Sie einen regulären Ausdruck tun.

Keine von beiden ist notwendigerweise sehr performant, also würde ich es nicht auf großen Datensätzen versuchen.

0

Es ist wahrscheinlich nicht die beste db Architektur, aber sie könnte wie so für Sie Zwecke reguläre Ausdrücke verwenden

SELECT * FROM people WHERE banned RLIKE '(^|@)Bob($|@)'

2

Wenn Sie die Liste immer wissen, von 2 oder 3 Namen zusammengesetzt ist (wie in Ihrem Kommentar angegeben), ist die einfachste Möglichkeit, für alle 3 möglichen Fälle zu überprüfen:

SELECT * 
FROM people 
WHERE list LIKE '[email protected]%' /* name in first position */ 
    OR list LIKE '%@[email protected]%' /* name in second position */ 
    OR list LIKE '%@bob' /* name in third, final position */ 
+0

Ich mag es, kann Indizes verwenden; aber 3 oder ... ooof. auf Leistung aber immer noch besser als ausgewählte Antwort ... müssen testen. es könnte tatsächlich schneller sein, jede Suche in ihrer eigenen Auswahl durchzuführen und die Ergebnisse zu vereinigen! – xQbert

+0

Leider können Indizes nicht für die zweiten beiden LIKEs verwendet werden, wenn der Platzhalter '% ...' am Anfang der Zeichenfolge steht. Wenn die Leistung ein großes Problem darstellt, kann die Umstrukturierung dieses Datenschemas der beste sein Problem. – jwoe

+0

True% bob% kann den Index nicht verwenden; aber die anderen 2 könnten. Immer noch wie es: P – xQbert