【问题标题】:mysql negation from multiple entires来自多个条目的mysql否定
【发布时间】:2015-02-22 05:02:40
【问题描述】:

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

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

我想获得所有使用 p2 但不使用 p3 的客户。是否可以在不使用嵌套查询的情况下实现这一点

我能够解决嵌套查询连接的问题。但由于嵌套连接太慢,我无法获得所需的性能。

【问题讨论】:

    标签: mysql join query-performance nested-queries


    【解决方案1】:

    是的,可以使用反连接模式。这是一个左连接,返回所有使用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
    

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

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

    【讨论】:

      【解决方案2】:

      在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
      

      【讨论】:

        猜你喜欢
        • 2015-04-01
        • 1970-01-01
        • 2019-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多