1

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

ios, ios development, freelance, new_project

我想查询该字段以检查值“ios”是否在逗号分隔列表中。请你能告诉我我该怎么做吗?

4

3 回答 3

5

使用 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 Autocomplete'吗?)。
  • 节省一些磁盘空间(标签只写一次)
  • 搜索速度很快。如果您已经知道要查找的标签并将它们预编译为标签 ID,它们会在运行时在人行道上留下 SQL 橡胶焦痕(索引搜索数值!)。并且不会编译的标签将不存在,您甚至在搜索开始之前就会知道这一点。
  • 更容易重命名标签
  • 可以容纳任意数量的标签(您有可能迟早会将某些标签截断为“iOS Developm”......)

我相信“CSV 字段”在SQL 反模式http://pragprog.com/book/bksqla/sql-antipatterns)中被审查(或),这是有充分理由的。

于 2012-08-27T20:38:28.803 回答
1

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

select *
  from mytable
 where concat(', ', tags, ',') like concat(', %ios%,')
于 2012-08-27T20:36:59.303 回答
0

第一个(简单):

WHERE tags LIKE '%ios,%'
于 2012-08-27T20:37:16.610 回答