У меня есть поле COLORS (varchar(50))
в моей таблице, SHIRTS
которое содержит строку с разделителями-запятыми, например 1,2,5,12,15,
. Каждое число представляет доступные цвета.
При выполнении запроса select * from shirts where colors like '%1%'
на получение всех красных рубашек (цвет = 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
источник
FIND_IN_SET в этом случае ваш друг
select * from shirts where FIND_IN_SET(1,colors)
источник
Взгляните на функцию FIND_IN_SET для MySQL.
SELECT * FROM shirts WHERE FIND_IN_SET('1',colors) > 0
источник
Это наверняка сработает, и я действительно попробовал:
lwdba@localhost (DB test) :: DROP TABLE IF EXISTS shirts; Query OK, 0 rows affected (0.08 sec) lwdba@localhost (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) lwdba@localhost (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 lwdba@localhost (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)
Попробуйте !!!
источник
Если набор цветов более или менее фиксирован, наиболее эффективным и наиболее читаемым способом будет использование строковых констант в вашем приложении, а затем использование
SET
типа MySQL с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
).источник
Если вы используете MySQL, вы можете использовать метод REGEXP ...
http://dev.mysql.com/doc/refman/5.1/en/regexp.html#operator_regexp
Итак, вы должны использовать:
SELECT * FROM `shirts` WHERE `colors` REGEXP '\b1\b'
источник
Фактически вы должны исправить схему своей базы данных, чтобы у вас было три таблицы:
Затем, если вы хотите найти все красные рубашки, вы должны выполнить такой запрос:
SELECT * FROM shirt, color WHERE color.color_name = 'red' AND shirt.shirt_id = shirtcolor.shirt_id AND color.color_id = shirtcolor.color_id
источник
select * from shirts where find_in_set('1',colors) <> 0
Работает для меня
источник
1. Для MySQL:
SELECT FIND_IN_SET(5, columnname) AS result FROM table
2. Для Postgres SQL:
SELECT * FROM TABLENAME f WHERE 'searchvalue' = ANY (string_to_array(COLUMNNAME, ','))
пример
select * from customer f where '11' = ANY (string_to_array(customerids, ','))
источник
Вы можете добиться этого с помощью следующей функции.
Выполните следующий запрос, чтобы создать функцию.
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');
источник
Все ответы не совсем правильные, попробуйте следующее:
select * from shirts where 1 IN (colors);
источник