我有一个映射表,用于存储展示位置和产品之间的映射。 The table structure像这样:
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);
答案 0 :(得分:2)
您可以使用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 :(得分:1)
您可以将聚合与特殊的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
(之前我假设您将包含这两种产品的产品分组)。
答案 2 :(得分:1)
MySQL中一种有趣的方式是:
SELECT placement_id
FROM mapping_table
GROUP BY placement_id
HAVING GROUP_CONCAT(DISTINCT product_name ORDER BY product_name) = ('product1,product2');