来自多个条目的mysql否定

时间:2014-12-24 02:46:05

标签: mysql join query-performance nested-queries

我有一个customer_products表,其中包含客户与正在使用的产品的映射

customer_id   product_id
c1           p1
c1           p2
c1           p3
c2           p1
c2           p2
c3           p1

我希望得到所有使用p2而不是p3的客户。是否可以在不使用嵌套查询的情况下实现此目的

我能够通过嵌套查询的连接解决问题。但由于嵌套连接速度太慢,我无法获得理想的性能。

2 个答案:

答案 0 :(得分:2)

是的,可以使用反连接模式。这是一个左连接,使用p2返回所有客户,以及匹配的行(相同customer_id)但使用p3,然后过滤掉所有匹配的行,在WHERE子句中使用谓词。

例如:

SELECT cp2.customer_id
  FROM customer_products cp2
  LEFT
  JOIN customer_products cp3
    ON cp3.customer_id = cp2.customer_id
   AND cp3.product_id = 'p3' 
 WHERE cp2.product_id = 'p2'
   AND cp3.product_id IS NULL

添加DISTINCT关键字GROUP BY cp2.customer_id子句以消除重复项(如果(customer_id,product_id)不能保证唯一。)

适当的索引将提高大型集的性能。

答案 1 :(得分:1)

在having子句中使用条件聚合的查询,以选择至少购买过product_id p2且从未购买过product_id p3的所有客户

select customer_id
from mytable
where product_id in ('p2','p3')
group by customer_id
having count(case when product_id = 'p2' then 1 end) > 0
and count(case when product_id = 'p3' then 1 end) = 0