Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wählen Sie alle aus, bei denen das Feld eine durch Komma getrennte Zeichenfolge enthält

Bei MySQL können Sie FIND_IN_SET() verwenden :

SELECT * FROM mytable WHERE FIND_IN_SET('ios ', tags) > 0;

http://dev.mysql .com/doc/refman/5.0/en/string-functions.html#function_find-in-set

Beachten Sie, dass FIND_IN_SET erwartet Strings als Komma getrennt, nicht Komma und Leerzeichen getrennt. Sie könnten also Probleme mit dem letzten Tag haben. Der wirklich beste Weg wäre, die Tabelle zu normalisieren; Andernfalls könnten Sie Leerzeichen aus den tags löschen Säule; Schließlich können Sie das Problem umgehen, indem Sie den tags ein Leerzeichen hinzufügen Spalte:

SELECT * FROM mytable WHERE FIND_IN_SET('ios ', CONCAT(tags,' ')) > 0;

Wenn die Anzahl der Tags begrenzt ist, sollten Sie erwägen, die Spalte in ein SET umzuwandeln . Dadurch wird die Effizienz erheblich verbessert.

AKTUALISIEREN

Außer dass ich die Leerzeichen falsch habe . Sie sind vorher die Saiten und nicht danach.

Also:

SELECT * FROM mytable WHERE FIND_IN_SET(' ios', CONCAT(' ', tags)) > 0;

Aber noch einmal, lass diese Leerzeichen los - sie sind nichts als Ärger :-)

AKTUALISIERUNG 2

Das obige funktioniert, okay. Aber das ist fast alles, was Sie zu meinen Gunsten sagen können. Die Lösung ist nicht nur ziemlich *in*effizient, sie macht das System auch fast nicht mehr wartbar (dort gewesen, das getan, das T-Shirt und einen zerkauten Arsch darunter bekommen). Also werde ich mich jetzt ein bisschen für die Normalisierung aussprechen, d. h. mindestens diese zwei weiteren Tabellen haben:

CREATE TABLE tags ( id      INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
                    tagName varchar(32) // I'm a bit of a cheapskate
);
CREATE TABLE has_tag ( tableid INTEGER, tagid INTEGER );

Wie viel ist das besser? Lass mich die Wege zählen.

  • Sie können problemlos flexiblere Abfragen hinzufügen ("hat alle Tags in iOS, C++, ..." oder "hat mindestens drei Tags darunter:( iOS, Python, SQL, .NET, Haskell )". Ja, Sie können dies mit FIND_IN_SET tun , aber glauben Sie mir, Sie werden es nicht genießen .
  • Sie haben ein kontrolliertes Wörterbuch von Tags, mit denen Sie überprüfen können, ob ein Tag bekannt ist (sowie auf einfache Weise Listen wie Dropdown-Kombinationsfelder oder -- hat jemand "jQuery Autocomplete" gesagt?) generiert.
  • spart Speicherplatz (Tags werden einmal geschrieben)
  • Suchvorgänge sind schnell . Wenn Sie die gesuchten Tags bereits kennen und sie in Tag-IDs vorkompilieren, hinterlassen sie bei der Ausführung SQL-Gummibrandspuren auf dem Bürgersteig (indizierte Suche nach einer Ganzzahl Wert!). Und Tags, die sich nicht kompilieren lassen, sind nicht vorhanden , und das wissen Sie schon, bevor die Suche beginnt.
  • macht das Umbenennen von Tags viel einfacher
  • kann jede Zahl aufnehmen von Tags (Sie riskieren, dass einige Tags früher oder später auf „iOS Developm“ gekürzt werden...)

Ich glaube, dass das "CSV-Feld" unter den SQL Antipatterns zensiert (oder) wird ( http://pragprog.com/book/bksqla/sql-antipatterns ), und das aus gutem Grund.