我有一个存储产品的数据库表。每种产品都可以有多种颜色。每种颜色都由其ID表示,而不是像“红色”,“黄色”等文本描述。当$_POST['colour']
数组内嵌到字符串(用逗号分隔)时,它会存储在表中:< / p>
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等的产品。
有人知道我该怎么做吗?
答案 0 :(得分:4)
如果您希望获得良好的性能,则需要对此表进行规范化,创建一个与产品表具有一对多关系的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'
答案 1 :(得分:2)
规范化表格。
同时,您可以使用:
SELECT *
FROM Product
WHERE FIND_IN_SET( 1, Colour )
OR FIND_IN_SET( 9, Colour ) --- etc
答案 2 :(得分:1)
为产品和颜色创建关联表,而不是在单个列中存储多个值。与带有colI的assocIroductsColors一样,productId和colorId包含一个Id col作为表的键
答案 3 :(得分:1)
与您已有的评论类似,我建议修改您的数据库:
product_id | colour
----------------------
1 | 1
1 | 2
2 | 10
3 | 7
3 | 9
但是,您也可以使用MySQL Regex Operators,特别是RLIKE
(“正则表达式”)来执行此操作。
SELECT *
FROM Product
WHERE Colour RLIKE '[[:<:]][19][[:>:]]'
正则表达式[[:<:]][19][[:>:]]
表示“匹配1或9([19]
),其中整个单词”。 [[:<:]]
和[[:>:]]
表示“单词边界”,因此给定的模式只会匹配1或9,如果它是一个完整的单词,而不是它是另一个数字的一部分。