MySQL中LIKE子句的替代方法

5
在我的数据库表中,我有一个字段用于存储类别。我将类别存储在以下格式中:1,12,15
现在,当我尝试从类别1中搜索产品时,我在查询中使用 LIKE 子句,例如:where (prod_catg LIKE %1,% or prod_catg LIKE %1% or prod_catg LIKE %,1%)
这会返回来自三个类别1、12和15的所有产品。但是我只想要来自类别1的产品。
我还尝试了IN子句,但没有结果。请问有什么其他替代方案吗?

4
你应该通过添加一个名为“category”的表格,并在主表中引用它来规范化你的模式。 - Dalen
3个回答

8
prod_catg LIKE '1,%' --matches when 1 is the first category
OR prod_catg LIKE '%,1,%' --matches when 1 is somewhere in the middle
OR prod_catg LIKE '%,1' --matches 1 when is the last category

无论如何,您最好通过添加类别表并在产品(主)表上引用它来重构架构。

编辑

另一种解决此问题的方法是使用REGEXP,这将导致更短的WHERE子句(这是我用来测试的内容):

DECLARE @regexp VARCHAR(100);
SET @regexp = '^1,.*|.*,1$|.*,1,.*';

SELECT
    '1,11,15,51,22,31' REGEXP @regexp AS test1,
    '51,11,15,1,22,31' REGEXP @regexp AS test2,
    '11,15,51,22,31,1' REGEXP @regexp AS test3,
    '7,11,15,51,22,31' REGEXP @regexp AS test4,
    '51,11,15,7,22,31' REGEXP @regexp AS test5,
    '11,15,51,22,31,7' REGEXP @regexp AS test6;

这将匹配您的prod_catg与正则表达式'^1,.*|.*,1$|.*,1,.*',如果匹配,则返回1(TRUE),否则返回0(FALSE)。然后您的WHERE子句将如下所示:
WHERE prod_catg REGEXP '^1,.*|.*,1$|.*,1,.*'

正则表达式的解释:
^1,.* --matches 1 at the beginning of a string followed by a `,` and any other char
.*,1$ --matches 1 at the end of a string preceded by a `,` and any other char
.*,1,.* --matches 1 between two `,` which are sourrounded by any other chars
| --is the OR operator

我相信这个正则表达式可以更加简洁,但我不太擅长正则表达式。
显然,您可以在正则表达式中更改要查找的类别(尝试将上面的1替换为7)。

6
WHERE FIND_IN_SET('1', prod_catg)

3

在产品和类别之间存在多对多关系。您应该创建一个新表来存储每个产品对应的类别(cat_ids)。您不应该有包含多个类别id的列。这样,您的选择将更加容易且速度更快。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接