映射表的仅条件-SQL

时间:2019-05-02 09:15:53

标签: mysql sql relational-division

我有一个映射表,用于存储展示位置和产品之间的映射。 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 1product 2对应的所有展示位置。一个展示位置可以映射到多个产品。因此,product 1 + product 2 + product 3product 1 + product 2的组合也是可能的。我需要选择仅分配给product 2product 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 个答案:

答案 0 :(得分:2)

您可以使用NOT EXISTS子句来检查每个展示位置是否没有产品不是product1product2的产品:

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