Pergunta
Eu tenho um campo na minha tabela para tags em algum conteúdo, separado por espaços, e no momento estou usando:
SELECT * FROM content WHERE tags LIKE '%$selectedtag%'"
Mas se a tag selecionada for elefante, ele selecionará conteúdo marcado com elefante grande e Elephantblah etc ...
Como faço para selecionar apenas o que quero com precisão?
Solução
SELECT * FROM content WHERE tags RLIKE '[[:<:]]elephant[[:>:]]'
Se sua mesa for MyISAM
, você pode usar isso:
SELECT * FROM content WHERE MATCH(tags) AGAINST ('+elephant' IN BOOLEAN MODE)
, que pode ser drasticamente melhorado, criando um FULLTEXT
índice nele:
CREATE FULLTEXT INDEX ix_content_tags ON content (tags)
, mas funcionará mesmo sem o índice.
Para que isso funcione, você deve ajustar @@ft_min_wold_len
Para indexar tags com menos de 4 caracteres, se você tiver algum.
Outras dicas
Você pode usar as expressões regulares do MySQL.
SELECT * FROM content WHERE tags REGEXP '(^| )selectedtag($| )'
Esteja ciente, porém, que o uso de expressões regulares acrescenta uma sobrecarga e pode ter um desempenho ruim em algumas circunstâncias.
Outra maneira simples, se você puder alterar os dados do banco de dados, é garantir que haja um espaço vazio antes da primeira tag e após a última; Um pouco como: "Animal de elefante". Dessa forma, você pode usar curingas.
SELECT * FROM content WHERE tags LIKE '% selectedtag %'
Eu consideraria um design diferente aqui. Isso constitui um relacionamento de muitos para muitos, para que você possa ter um tags
Tabela e uma tabela de junção. Em geral, a atomicidade dos dados economiza você de muitas dores de cabeça.
Um bônus adicional dessa abordagem é que você pode renomear uma tag sem precisar editar todas as entradas que contêm essa tag.
R: Você precisa criar uma tabela de tags separada que aponte para o conteúdo com o contentId e contém uma palavra -chave e depois:
select a.*
from content a,tags b
where a.id=b.contentid
group by a.id;
B: Coloque uma vírgula entre as tags e antes e as mais ",bigelephant,elephant,"
, então use like "%,elephant,%"
WHERE tags LIKE '% '{$selectedtag}' %'
OR tags LIKE ''{$selectedtag}' %'
OR tags LIKE '% '{$selectedtag}''
O '%' é um curinga no SQL. Remova os curingas e você obterá com precisão o que pede.
Refona o design da tabela, mas por enquanto, se você usar espaços para delimitar entre tags, você pode fazer isso:
SELECT * FROM content WHERE tags LIKE '% elephant %';
Apenas certifique -se de liderar e terminar com um espaço também (ou substitua os espaços por vírgulas se estiver fazendo dessa maneira)
Novamente, a melhor opção é configurar um relacionamento de muitos para muitos em seu banco de dados, mas suspeito que você esteja procurando uma correção única rápida e suja.