我有一个customer_products表,其中包含客户与正在使用的产品的映射
customer_id product_id
c1 p1
c1 p2
c1 p3
c2 p1
c2 p2
c3 p1
我希望得到所有使用p2而不是p3的客户。是否可以在不使用嵌套查询的情况下实现此目的
我能够通过嵌套查询的连接解决问题。但由于嵌套连接速度太慢,我无法获得理想的性能。
答案 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