选择所有where字段包含以逗号分隔的字符串

时间:2012-08-27 20:35:23

标签: mysql

我有一个名为'tags'的字段,其中包含以逗号分隔的标记列表,例如:

ios, ios development, freelance, new_project

我想查询该字段以检查值'ios'是否在逗号分隔列表中。请问你能告诉我怎么做到这一点?

3 个答案:

答案 0 :(得分:4)

使用MySQL,您可以使用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

请注意,FIND_IN_SET要求字符串逗号分隔,而不是逗号和空格分隔。所以你可能有最后一个标签的问题。真正最好的方法是规范化表格;否则你可能会从tags列中删除空格;最后,您可以通过向tags列添加空格来解决此问题:

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

如果标签数量有限,您可以考虑将列转换为SET。这将大大提高效率。

<强>更新

除了我得到空格错误。它们之前字符串而不是之后。

所以:

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

但是,再次摆脱那些空间 - 它们只是麻烦: - )

更新2

以上作品,好的。但是,几乎所有你都可以说对我有利。不仅解决方案非常高效,它还使系统无法维护(在那里,完成了,得到了T恤和一个被咀嚼的屁股)。所以我现在稍微有点赞成规范化,即至少再增加这两个表:

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

这好多少?让我数一下。

  • 您可以轻松添加更灵活的查询(“包含iOS,C ++中的所有标记......”或“其中至少包含三个标记:( iOS,Python,SQL,.NET,Haskell)”。是的,您可以使用FIND_IN_SET执行此操作,但相信我,您将无法享受
  • 你有一个受控词典的标签,它可以让你检查是否有任何标签(以及轻松生成下拉组合框之类的列表,或者 - 有人说' jQuery自动完成'?)。
  • 保存一些磁盘空间(标签只写一次)
  • 搜索快速。如果你已经知道你正在寻找的标签并将它们预先编译成标签ID,它们将在运行时在人行道上留下SQL橡胶焦痕(索引搜索整数值!)。并且不会编译的标签将不在那里,甚至在搜索开始之前你就会知道这一点。
  • 可以更轻松地重命名标记
  • 可以保存任意数量的标签(您有可能迟早会将某些标签截断为'iOS Developm'......)

我认为“CSV字段”是 SQL Antipatterns http://pragprog.com/book/bksqla/sql-antipatterns)中的cens(或)ed,并且有充分的理由。

答案 1 :(得分:1)

这是一个适用于逗号分隔列表的简单方法:

select *
  from mytable
 where concat(', ', tags, ',') like concat(', %ios%,')

答案 2 :(得分:0)

首先(简单):

WHERE tags LIKE '%ios,%'