Com o MySQL, você pode usar
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
Observe que
FIND_IN_SET
espera que as strings sejam vírgulas separados, não vírgula e espaço separados. Então você pode ter problemas com a última tag. A melhor maneira seria normalizar a tabela; caso contrário, você pode eliminar espaços das tags
coluna; finalmente você pode contornar o problema adicionando um espaço às tags
coluna:SELECT * FROM mytable WHERE FIND_IN_SET('ios ', CONCAT(tags,' ')) > 0;
Se o número de tags for limitado, considere converter a coluna em um
SET
. Isso melhorará muito a eficiência. ATUALIZAÇÃO
Exceto que eu tenho os espaços errados . Eles estão antes as cordas e não depois.
Então:
SELECT * FROM mytable WHERE FIND_IN_SET(' ios', CONCAT(' ', tags)) > 0;
Mas, novamente, livre-se desses espaços - eles não são nada além de problemas :-)
ATUALIZAÇÃO 2
O acima funciona, ok. Mas, isso é quase tudo que você pode dizer a meu favor. Não apenas a solução é bastante *in*eficiente, mas também torna o sistema quase insustentável (estive lá, fiz isso, peguei a camiseta e uma bunda mastigada por baixo). Então, agora vou insistir um pouco a favor da normalização, ou seja, ter pelo menos mais duas tabelas:
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 isso é melhor? Deixe-me contar os caminhos.
- você pode facilmente adicionar consultas mais flexíveis ("tem todas as tags em iOS, C++, ..." ou "tem pelo menos três tags entre estas:( iOS, Python, SQL, .NET, Haskell )". Sim, você pode fazer isso com
FIND_IN_SET
, mas acredite, você não vai gostar . - você tem um dicionário controlado de tags, que permite que você verifique se alguma tag é conhecida (além de gerar listas facilmente, como caixas de combinação suspensas ou -- alguém disse 'jQuery Autocomplete'?).
- economiza espaço no disco (as tags são gravadas uma vez)
- as pesquisas são rápidas . Se você já conhece as tags que está procurando e as pré-compila em IDs de tag, elas deixarão marcas de queimadura de borracha SQL no pavimento durante a execução (pesquisa indexada por um inteiro valor!). E tags que não compilam não estarão lá , e você saberá disso antes mesmo do início da pesquisa.
- torna muito mais fácil renomear tags
- pode conter qualquer número de tags (você corre o risco de ter alguma tag truncada para 'iOS Developm' mais cedo ou mais tarde...)
Acredito que o "campo CSV" seja cens(ou) entre os SQL Antipatterns ( http://pragprog.com/book/bksqla/sql-antipatterns ), e com razão.