#mysql #sql #postgresql
#mysql #sql #postgresql
Вопрос:
У меня есть таблица, в которой указаны отношения продуктов и цветов. Каждый продукт имеет один или несколько цветов. Возможно ли выполнить запрос, который возвращает только те продукты, которые имеют только один цвет и желаемый цвет?
Значение из api: color_slug = белый ;
Пример таблицы :
color_table
---------- ------------
| color_id | color_slug |
---------- ------------
| 1 | white |
| 2 | blue |
| 3 | black |
| 4 | green |
| 5 | red |
| 6 | yellow |
---------- ------------
product_table
------------ --------------
| product_id | product_name |
------------ --------------
| 1 | shoes |
| 2 | shorts |
| 3 | t-shirt |
| 4 | jacket |
| 5 | watch |
| 6 | glasses |
------------ --------------
pc_relation
---- ------------ ----------
| id | product_id | color_id |
---- ------------ ----------
| 1 | 1 | 5 |
| 2 | 1 | 1 |
| 3 | 2 | 1 |
| 4 | 2 | 4 |
| 5 | 2 | 3 |
| 6 | 3 | 2 |
| 7 | 4 | 1 |
| 8 | 5 | 5 |
| 9 | 5 | 6 |
| 10 | 6 | 1 |
---- ------------ ----------
Выберите уникальные значения цвета (если я укажу, ГДЕ color_id = 1, цвета продукта не будут длиннее только одного цвета) :
SELECT product_id
FROM pc_relation
// WHERE color_id = 1
GROUP BY product_id
HAVING MIN(color_id) = MAX(color_id)
pc_relation.id = 6,7,10
SELECT *
FROM color_table
INNER JOIN pc_relation ON pc_relation.color_id = color_table.color_id
INNER JOIN product_table ON pc_relation.product_id = product_table.product_id
WHERE colors.color_slug = 'white'
Требуемые значения (color_slug = белый):
pc_relation.id = 7,10
product_table.product_name = jacket, glasses
* все комбинации уникальны и проиндексированы. Например, у меня не может быть одного продукта с одним и тем же цветом дважды.
Комментарии:
1. это mysql или postgresql?
Ответ №1:
Вы на правильном пути с вашим первым запросом. Переместите сравнение цветов в HAVING
предложение:
SELECT product_id
FROM pc_relation
GROUP BY product_id
HAVING MIN(color_id) = MAX(color_id) AND
MIN(color_id) = 1;
Вы также можете сформулировать это с помощью NOT EXISTS
:
select r.*
from pc_relation r
where r.color_id = 1 and
not exists (select 1
from pc_relation r2
where r2.product_id = r.product_id and r2.color_id <> r.color_id
);
Однако GROUP BY
метод является более общим.
Комментарии:
1. Уже сделал это, но без MIN на MIN(color_id) = 1; Я попробую это сейчас.
2. Почему значение MIN имеет значение? Это сработало: MIN(color_table.color_slug) = ‘white’
3. @bmpf_pt . , , я не совсем понимаю вопрос. Вам нужна функция агрегирования в
having
предложении.