我有一个存储产品的数据库表。每种产品都可以有多种颜色。每种颜色都由其ID表示,而不是像"红色"、"黄色"等文本描述。当$_POST['colour']
数组内爆为字符串(用逗号分隔)时,它将存储在表中:
product_id | colour
----------------------
1 | 1,2
2 | 10
3 | 7,9
最近,我尝试创建一个搜索表单,可以选择多种颜色并搜索数据库表,看看是否有任何产品在搜索数组中至少包含一种颜色。因此,如果访问者想查看颜色1和9的产品,我需要在"颜色"栏中搜索这两个值。
我不能使用WHERE colour IN (1,9)
,因为我认为只有当列中有一个值(而不是多个值的分隔数组)时,它才有效。我也不能使用WHERE colour LIKE 1 OR WHERE colour LIKE 9
,因为它会退回颜色ID为10、11或12等的产品。
有人知道我该怎么做吗?
如果您想获得良好的性能,请创建一个与product表具有一对多关系的productColor表
话虽如此:
SELECT *
FROM Product
WHERE Colour LIKE '%,1,%' OR Colour LIKE '1,% OR COLOUR LIKE '%,1'
OR Colour LIKE '%,9,%' OR Colour LIKE '9,% OR COLOUR LIKE '%,9'
规范化表格。
同时,您可以使用:
SELECT *
FROM Product
WHERE FIND_IN_SET( 1, Colour )
OR FIND_IN_SET( 9, Colour ) --- etc
为产品和颜色创建一个关联表,而不是将多个值存储在一列中。与assocProductsColors一样,productId和colorId的col包含一个Id col作为表的键
与您已有的注释类似,我建议修改您的数据库,使其具有:
product_id | colour
----------------------
1 | 1
1 | 2
2 | 10
3 | 7
3 | 9
但是,您也可以使用MySQL Regex Operators,特别是RLIKE
("Regex-like")来执行此操作。
SELECT *
FROM Product
WHERE Colour RLIKE '[[:<:]][19][[:>:]]'
正则表达式[[:<:]][19][[:>:]]
的意思是"匹配1或9([19]
),其中它是整个单词"。[[:<:]]
和[[:>:]]
的意思是"单词边界",因此给定的模式只有在它本身是一个完整单词的情况下才会匹配1或9,而不是在它是另一个数字的一部分的情况下。