Запрос MySQL поиск значений в строке, разделенной запятыми



у меня есть поле COLORS (varchar(50)) в таблице SHIRTS который содержит строку с разделителями-запятыми, например 1,2,5,12,15,. Каждое число представляет Доступные цвета.



при выполнении запроса select * from shirts where colors like '%1%' чтобы получить все красные рубашки (цвет=1), я также получаю рубашки, цвет которых серый (=12) и оранжевый (=15).



как я должен переписать запрос, чтобы выбрать только цвет 1, а не все цвета, содержащие число 1?

634   10  

10 ответов:

классическим способом было бы добавить запятые слева и справа:

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)

дайте ему попробовать !!!

если набор цветов более или менее фиксирован, наиболее эффективным и наиболее читаемым способом было бы использовать строковые константы в вашем приложении, а затем использовать MySQL SET типа FIND_IN_SET('red',colors) в ваши запросы. При использовании SET типа FIND_IN_SET, MySQL использует одно целое число для хранения всех значений и использует binary "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'

вы должны исправить схему базы данных так, что у вас есть три таблицы:

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
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');

надеюсь, что это поможет.

все ответы не совсем правильные, попробуйте это:

select * from shirts where 1 IN (colors);

Comments

    Ничего не найдено.