2015-10-05 66 views
0

我想查询我们的数据库以提取客户数据。关键部分是:与MySQL并肩作战不存在

拉出所有未购买的客户/订单product_a

这将列出已购买的客户/订单,product_b,product_c和product_d。

但它需要确保客户还没有购买过product_a。我需要排除他们。

这是否正确的方式去关于NOT EXISTS?我仍然觉得它包含了一些买了product_a的记录。

SELECT 
    * 
FROM 
    orders 
JOIN customers AS cus ON orders.CustomerNumber = cus.CustomerNumber 
WHERE 
    product != 'product_a' 
OR (
    HomeTelephone = '' 
    AND MobileTelephone != '' 
) 
AND NOT EXISTS (
    SELECT 
     OrderNumber 
    FROM 
     orders AS o 
    JOIN customers AS c ON o.CustomerNumber = c.CustomerNumber 
    WHERE 
     c.EmailAddress = cus.EmailAddress 
    AND Product = 'product_a' 
    AND completed = 1 
) 
ORDER BY 
    orderdate 

如果没有NOT EXISTS语句,即使他们单独购买了product_a,也可以包含客户记录吗?

+0

你的问题是你'WHERE'子句中的'或'。它将包括那些有'HomeTelephone =''和MobileTelephone!='''的记录。你对这部分查询的意图是什么? –

+0

在where子句中...将括号放在产品之前和OR括号之后,以查看查询处理器实际上在做什么。然后分析你真的想做什么。 OR可能不在你想象的地方工作。 –

回答

1

您的不存在是有点关闭和where product != 'product_a'是多余的。

SELECT 
    * 
FROM 

    orders AS o1 
    JOIN customers AS cus ON o1.CustomerNumber = cus.CustomerNumber 
WHERE 
    cus.HomeTelephone = '' 
    AND cus.MobileTelephone != '' 
    AND NOT EXISTS (
     SELECT 
      1 
     FROM 
      orders o2 
     WHERE 
      o2.CustomerNumber = cus.CustomerNumber 
      AND Product = 'product_a' 
      AND completed = 1 
    ) 
ORDER BY 
    o1.orderdate 

这会给你的客户他们的订单。根据您的描述,如果您只需要客户信息,则可以在查询的第一部分中排除加入订单,并使用“不存在”来确定该客户是否购买了product_a。

SELECT 
    * 
FROM 
    customers cus 
WHERE 
    HomeTelephone = '' 
    AND MobileTelephone != '' 
    AND NOT EXISTS (
     SELECT 
      1 
     FROM 
      orders o 
     WHERE 
      o.CustomerNumber = cus.CustomerNumber 
      AND Product = 'product_a' 
      AND completed = 1 
    ) 
+0

你是第一次查询SEEMS是一个将会得到这个工作的人 - 但子查询正在匆匆离开。我不知道我还能做些什么来优化它。没有它的几秒钟,它似乎无限! –

+0

订单表是否有客户编号索引?或产品?或完成? – JamieD77

+0

这就是它!谢谢!现在超级快。 –

0
SELECT c.* 
    FROM customers c 
    LEFT 
    JOIN orders o 
    ON o.CustomerNumber = c.CustomerNumber 
    AND o.product = 'product_a' 
WHERE o.CustomerNumber IS NULL