Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Selecione tudo onde o campo contém uma string separada por vírgula


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.