Mysql
 sql >> Database >  >> RDS >> Mysql

Seleziona tutto dove il campo contiene una stringa separata da virgola

Con MySQL, puoi usare FIND_IN_SET() :

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

Nota che FIND_IN_SET si aspetta che le stringhe siano virgola separati, non virgola e spazio separato. Quindi potresti avere problemi con l'ultimo tag. Il modo migliore sarebbe normalizzare la tabella; altrimenti potresti cancellare gli spazi dai tags colonna; infine puoi aggirare il problema aggiungendo uno spazio ai tags colonna:

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

Se il numero di tag è limitato, potresti considerare di convertire la colonna in un SET . Ciò migliorerà notevolmente l'efficienza.

AGGIORNAMENTO

Solo che ho gli spazi sbagliati . Sono prima le stringhe e non dopo.

Quindi:

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

Ma ancora una volta, sbarazzati di quegli spazi:non sono altro che problemi :-)

AGGIORNAMENTO 2

Quanto sopra funziona, ok. Ma questo è quasi tutto ciò che puoi dire a mio favore. Non solo la soluzione è abbastanza *in*efficiente, ma rende anche il sistema quasi ingestibile (ci sono stato, l'ho fatto, ho la maglietta e un culo masticato sotto lo stesso). Quindi ora parlerò un po' a favore della normalizzazione, cioè avere almeno queste due tabelle in più:

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 );

Quanto è meglio? Fammi contare i modi.

  • puoi aggiungere facilmente query più flessibili ("ha tutti i tag in iOS, C++, ..." o "ha almeno tre tag tra questi:( iOS, Python, SQL, .NET, Haskell )". Sì, puoi farlo con FIND_IN_SET , ma fidati, non ti divertirai .
  • hai un dizionario controllato di tag, che ti consente di verificare se un tag è noto (oltre a generare facilmente elenchi come caselle combinate a discesa o -- qualcuno ha detto "Completamento automatico jQuery"?).
  • salva un po' di spazio su disco (i tag vengono scritti una sola volta)
  • le ricerche sono veloci . Se conosci già i tag che stai cercando e li precompili in ID tag, lasceranno segni di bruciature di gomma SQL sul pavimento durante l'esecuzione (ricerca indicizzata di un intero valore!). E i tag che non verranno compilati non ci saranno , e lo saprai anche prima che inizi la ricerca.
  • rende molto più semplice rinominare i tag
  • può contenere qualsiasi numero di tag (rischi prima o poi che qualche tag venga troncato in 'iOS Developm'...)

Credo che il "campo CSV" sia censurato (o) classificato tra gli SQL Antipatterns ( http://pragprog.com/book/bksqla/sql-antipatterns ), e per una buona ragione.