与 MySQL 不存在斗争
Posted
技术标签:
【中文标题】与 MySQL 不存在斗争【英文标题】:Struggling with MySQL NOT EXISTS 【发布时间】:2015-10-05 15:42:21 【问题描述】:我正在尝试查询我们的数据库以提取客户数据。关键部分是:
拉出所有未购买product_a的客户/订单。
这将列出已购买 product_b、product_c 和 product_d 的客户/订单。
但它需要确保客户从未购买过product_a。我需要排除它们。
这是处理“不存在”的正确方法吗?我仍然觉得它包括一些购买 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,也可以包含客户记录,对吗?
【问题讨论】:
你的问题是你的WHERE
子句中的OR
。它将包括那些具有HomeTelephone = '' AND MobileTelephone != ''
的记录。您对这部分查询的意图是什么?
在 where 子句中... 将括号放在 product 之前和 OR 括号之后,以查看查询处理器实际在做什么。然后分析你真正想要做什么。 OR 的作用可能与您想象的不同。
【参考方案1】:
Your Not Exists 有点偏离,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
这将为您提供客户的订单。不过,根据您的描述,如果您只想要客户信息,您可以在查询的第一部分排除订单的连接,并使用 Not Exist 来确定该客户是否购买了 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
)
【讨论】:
您的第一个查询似乎是要让这个工作的人 - 但子查询正在消失。我不知道我还能做些什么来优化它。没有子它的几秒钟,它似乎无限! 订单表是否有关于 customernumber 的索引?还是产品?还是完成了? 就是这样!!谢谢!现在超级快。 嗨 JamieD77 - 我在我们的订单表中为 CustomerNumber 添加了一个“正常”索引,上面的查询开始绝对飞!但它似乎扼杀了我们在网站上通过 php 运行的 SELECT 查询,该查询只是简单地拉回今天的订单,并与其他表的一些其他连接以提取各种信息。任何想法为什么?今天为了让线上系统顺利运行,不得不删除索引....【参考方案2】:SELECT c.*
FROM customers c
LEFT
JOIN orders o
ON o.CustomerNumber = c.CustomerNumber
AND o.product = 'product_a'
WHERE o.CustomerNumber IS NULL
【讨论】:
以上是关于与 MySQL 不存在斗争的主要内容,如果未能解决你的问题,请参考以下文章
命名空间“Microsoft”中不存在类型或命名空间名称“Bot”?