ТОЛЬКО В условии для таблицы сопоставления - SQL - PullRequest
0 голосов
/ 02 мая 2019

У меня есть таблица сопоставлений, в которой хранятся сопоставления между местами размещения и продуктами. Структура таблицы выглядит следующим образом:

CREATE TABLE IF NOT EXISTS mapping_table (
  id int unsigned NOT NULL AUTO_INCREMENT,
  placement_id int NOT NULL,
  product_name varchar(200) NOT NULL,
  PRIMARY KEY (id)
);

INSERT INTO mapping_table (id, placement_id, product_name) VALUES
( 1, 2, 'product1'),
( 2, 1, 'product1'),
( 3, 2, 'product2'),
( 4, 1, 'product2'),
( 5, 2, 'product3'),
( 6, 4, 'product1'),
( 7, 2, 'product3'),
( 8, 4, 'product3'),
( 9, 1, 'product1'),
(10, 3, 'product1'),
(11, 4, 'product1'),
(12, 3, 'product2'),
(13, 4, 'product2'),
(14, 2, 'product1'),
(15, 4, 'product1'),
(16, 2, 'product3');

Теперь мне нужно выбрать все места размещения, соответствующие product 1 и product 2.Возможно, что одно размещение может быть сопоставлено с несколькими продуктами.Таким образом, комбинация product 1 + product 2 + product 3 возможна и product 1 + product 2 также возможна.Мне нужно выбрать места размещения, которые относятся только к product 2 или product 1, а не к product 3 или другим продуктам.Когда я использую IN (), как в следующем запросе, он выдаст результаты, включая product3, даже если такое сопоставление будет.Я хотел бы избежать тех мест размещения, в которых в сопоставлении есть продукт 3.

SELECT placement_id FROM mapping_table
WHERE product_name IN ('product1', 'product2') ;

Мне нужно

SELECT placement_id FROM mapping_table
WHERE product_name ONLY_IN ('product1', 'product2') AND NOT IN ('product3','product4', etc);

Ответы [ 3 ]

2 голосов
/ 02 мая 2019

Вы можете использовать предложение NOT EXISTS, чтобы проверить, что в каждом месте размещения нет продукта, который не product1 или product2:

SELECT DISTiNCT placement_id 
FROM mapping_table m1
WHERE NOT EXISTS (SELECT *
                  FROM mapping_table m2
                  WHERE m2.placement_id = m1.placement_id
                    AND m2.product_name NOT IN ('product1', 'product2'));

выход

placement_id
1
3

Обновлено SQLFiddle

1 голос
/ 02 мая 2019

Интересный способ в MySQL:

SELECT placement_id
FROM mapping_table
GROUP BY placement_id
HAVING GROUP_CONCAT(DISTINCT product_name ORDER BY product_name) = ('product1,product2');
1 голос
/ 02 мая 2019

Вы можете использовать агрегацию со специальным предложением HAVING:

SELECT placement_id
FROM mapping_table
GROUP BY placement_id
HAVING COUNT(CASE WHEN product_name     IN ('product1', 'product2') THEN 1 END) > 0
AND    COUNT(CASE WHEN product_name NOT IN ('product1', 'product2') THEN 1 END) = 0

(Ранее я предполагал, что вы группы, содержащие оба продукта).

...