如何用LIKE选择号码?

时间:2014-07-27 14:47:23

标签: mysql sql sql-like

我有一堆产品和一堆类别页面。一种产品可以分为多个类别。所以在我的数据库中,我有一个带有“类别”列的产品表。在此列中,我存储了当前产品存储的所有类别的ID,它是一个用分号分隔的字符串。

示例:1;5;23;35;49;

当我浏览到类别页面ID 5时,我想查看其category-column中包含5;的所有产品。我目前通过

来做到这一点
SELECT * FROM products WHERE categories LIKE "%".category.";%"

问题是这不仅仅匹配5.它匹配15;25;

所以问题:

  1. 如何确保我只选择我想要的号码?如果类别为“5”,我不希望它匹配15,25,35等。
  2. 也许这是存储类别ID的一种非常糟糕的方式。您是否有任何关于存储属于哪个类别的产品的不同方式的建议?

3 个答案:

答案 0 :(得分:1)

其他人提到过联结表是设计数据库的正确方法。 SQL有一个非常好的数据结构用于存储列表。它不被称为“字符串”,它被称为“表”。

但是,有时人们会坚持使用这种格式的数据,并且需要使用它。在这种情况下,关键是将分隔符放在两边以防止出现问题:

SELECT *
FROM products
WHERE concat(';', categories) LIKE "%;".category.";%"

您的列表已经以分号结尾,因此没有必要。

另一个更典型的MySQL解决方案是find_in_set()

SELECT *
FROM products
WHERE find_in_set(category, replace(categories, ';', ',') > 0;

它专为逗号分隔的列表而设计。奇怪的是MySQL在以这种方式存储列表时支持这样的功能通常是一个坏主意,但确实如此。不过,出于性能原因(以及其他原因),联结表更好。

答案 1 :(得分:0)

回答/评论你的两个问题:

  1. 我能想到的唯一可以在不修改模式的情况下执行此操作(参见#2)的方法是使用MySQL正则表达式,但这不是一个好主意。有关文档,请参阅http://dev.mysql.com/doc/refman/5.1/en/regexp.html

  2. 你是对的 - 这不是存储类别的好方法。你想要的是一个连接,也称为连接表(见http://en.wikipedia.org/wiki/Junction_table)。一种方法是拥有三个表:productcategoryproduct_categories表。产品和类别将具有您已有的唯一ID,product_categories表将包含两列:product_id和category_id。如果产品1属于类别10和11,那么product_categories表中将有两行:1,10和1,11。

  3. 如果您需要更多帮助,我可以详细说明,但这应该让您开始正确地重新构建数据库(更多)。

答案 2 :(得分:-2)

您可以尝试将喜欢的条件更改为“%;”。category。“;%”