我在我的表SHIRTS
中有一个字段COLORS (varchar(50))
,其中包含逗号分隔的字符串,如1,2,5,12,15,
。每个数字代表可用的颜色。MySQL查询查找逗号分隔字符串中的值
当运行查询select * from shirts where colors like '%1%'
以获得所有红色衬衫(color = 1)时,我也会得到颜色为灰色(= 12)和橙色(= 15)的衬衫。
我该如何重写查询,以便仅选择颜色1而不是所有包含数字1的颜色?
我在我的表SHIRTS
中有一个字段COLORS (varchar(50))
,其中包含逗号分隔的字符串,如1,2,5,12,15,
。每个数字代表可用的颜色。MySQL查询查找逗号分隔字符串中的值
当运行查询select * from shirts where colors like '%1%'
以获得所有红色衬衫(color = 1)时,我也会得到颜色为灰色(= 12)和橙色(= 15)的衬衫。
我该如何重写查询,以便仅选择颜色1而不是所有包含数字1的颜色?
经典的方法是逗号添加到左,右:
select * from shirts where CONCAT(',', colors, ',') like '%,1,%'
但find_in_set也适用:
select * from shirts where find_in_set('1',colors) <> 0
如果你使用MySQL,还有就是你可以使用的方法REGEXP ...
http://dev.mysql.com/doc/refman/5.1/en/regexp.html#operator_regexp
,那么你可以使用:
SELECT * FROM `shirts` WHERE `colors` REGEXP '\b1\b'
找不到这个,尽管我很确定这是我的错。感谢密友。 – bikey77 2011-02-17 19:36:27
看看的用于MySQL的FIND_IN_SET函数。
SELECT *
FROM shirts
WHERE FIND_IN_SET('1',colors) > 0
注意:set中的find不使用表上的索引。 – edigu 2017-02-25 13:43:44
你应该真正解决您的数据库模式,让您有三个表:
shirt: shirt_id, shirt_name
color: color_id, color_name
shirtcolor: shirt_id, color_id
然后,如果你想找出所有红色的衬衫,你会做一个查询,如:
SELECT *
FROM shirt, color
WHERE color.color_name = 'red'
AND shirt.shirt_id = shirtcolor.shirt_id
AND color.color_id = shirtcolor.color_id
FIND_IN_SET是你在这种情况下
select * from shirts where FIND_IN_SET(1,colors)
这将肯定工作的朋友,其实我尝试过了:
[email protected] (DB test) :: DROP TABLE IF EXISTS shirts;
Query OK, 0 rows affected (0.08 sec)
[email protected] (DB test) :: CREATE TABLE shirts
-> (<BR>
-> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> ticketnumber INT,
-> colors VARCHAR(30)
->);<BR>
Query OK, 0 rows affected (0.19 sec)
[email protected] (DB test) :: INSERT INTO shirts (ticketnumber,colors) VALUES
-> (32423,'1,2,5,12,15'),
-> (32424,'1,5,12,15,30'),
-> (32425,'2,5,11,15,28'),
-> (32426,'1,2,7,12,15'),
-> (32427,'2,4,8,12,15');
Query OK, 5 rows affected (0.06 sec)
Records: 5 Duplicates: 0 Warnings: 0
[email protected] (DB test) :: SELECT * FROM shirts WHERE LOCATE(CONCAT(',', 1 ,','),CONCAT(',',colors,',')) > 0;
+----+--------------+--------------+
| id | ticketnumber | colors |
+----+--------------+--------------+
| 1 | 32423 | 1,2,5,12,15 |
| 2 | 32424 | 1,5,12,15,30 |
| 4 | 32426 | 1,2,7,12,15 |
+----+--------------+--------------+
3 rows in set (0.00 sec)
给它是一个尝试!
如果一组颜色或多或少是固定的,最有效和最可读的方法是在您的应用中使用字符串常量,然后在您的查询中使用MySQL的SET
类型和FIND_IN_SET('red',colors)
。当使用SET
类型和FIND_IN_SET时,MySQL使用一个整数来存储所有值,并使用二进制"and"
操作来检查值是否比扫描逗号分隔字符串更有效。
在SET('red','blue','green')
,'red'
将内部存储为1
,'blue'
将内部作为2
存储和'green'
将内部作为4
被存储。值'red,blue'
将被存储为3
(1|2
)和'red,green'
作为5
(1|4
)。
所有的答案是不是真的正确,试试这个:
select * from shirts where 1 IN (colors);
select * from shirts where find_in_set('1',colors) <> 0
对我的作品
您可以通过下面的函数实现这一目标。
运行以下查询来创建函数。
DELIMITER ||
CREATE FUNCTION `TOTAL_OCCURANCE`(`commastring` TEXT, `findme` VARCHAR(255)) RETURNS int(11)
NO SQL
-- SANI: First param is for comma separated string and 2nd for string to find.
return ROUND (
(
LENGTH(commastring)
- LENGTH(REPLACE (commastring, findme, ""))
)/LENGTH(findme)
);
而且这样调用
msyql> select TOTAL_OCCURANCE('A,B,C,A,D,X,B,AB', 'A');
这个功能希望这会有所帮助。
我可以通过正则表达式来做到这一点,但更好的解决方案是将衬衫的颜色分解成单独的表格(颜色),并使用颜色/衬衫的ID来连接它们来使用连接表格(shirt_colors)。 – ceejayoz 2011-02-17 18:36:50
我不能相信6答案*没有*他们提到MySQL的SET数据类型.. – ColinM 2012-12-14 15:30:51
检查此: http://stackoverflow.com/questions/12559876/finding-exact-value-from-a-comma -separated-string-in-php-mysql – Alireza 2014-06-28 06:55:14