Проблема с предложением MySQL WHERE и разделенными строками - PullRequest
1 голос
/ 15 января 2012

У меня есть таблица базы данных, в которой хранятся товары. Каждый продукт может иметь несколько цветов. Каждый цвет представлен своим идентификатором, а не текстовым описанием, таким как «Красный», «Желтый» и т. Д. Когда массив $_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, потому что он будет возвращать продукты с идентификатором цвета 10 или 11 или 12 и т. Д.

Кто-нибудь знает, как я могу это сделать?

Ответы [ 4 ]

4 голосов
/ 15 января 2012

Эта таблица должна быть нормализована, если вы хотите получить хорошую производительность, создайте таблицу 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'
2 голосов
/ 15 января 2012

Нормализовать таблицу.

В то же время, вы можете использовать:

SELECT *
FROM Product
WHERE FIND_IN_SET( 1, Colour )
   OR FIND_IN_SET( 9, Colour )           --- etc
1 голос
/ 15 января 2012

Как и ваши комментарии, я бы предложил изменить вашу базу данных так:

product_id | colour
----------------------
1          | 1
1          | 2
2          | 10
3          | 7
3          | 9

Однако для этого вы также можете использовать Операторы MySQL Regex , в частности RLIKE ("regex like").

SELECT *
FROM Product
WHERE Colour RLIKE '[[:<:]][19][[:>:]]'

Регулярное выражение [[:<:]][19][[:>:]] означает «соответствует 1 или 9 ([19]), где это целое слово ». [[:<:]] и [[:>:]] означают «границу слова», поэтому данный шаблон будет соответствовать 1 или 9, если оно само является целым словом, а не если оно является частью другого числа.

1 голос
/ 15 января 2012

Создайте таблицу связей для продуктов и цветов, а не храните несколько товаров в одном столбце.Как и атрибуты assocProductsColors с col для productId и colorId, в качестве ключа для таблицы включается идентификатор col

...