在连接表中两个日期之间没有记录的情况下

4

我正在尝试选择过去2个月内完全没有销售的所有商品。

我尝试使用此查询,但结果并不如预期:

SELECT SalesDescription FROM Items I
LEFT JOIN Orders_Items OI
ON OI.ItemID=I.ItemID

LEFT JOIN Orders O
 ON O.OrderID=OI.OrderID

WHERE OrderTime NOT BETWEEN date_sub(curdate(), interval 2 month)
AND date_sub(curdate(), interval 1 day)
Group By I.ItemID

基本上,我想从项目表中获取所有记录(按项目ID分组),但前提是它们在过去两个月内没有被订购。
当我进行上述连接时,生成的表格如下:
Name        OrderID     OrderDate
Widget A     1          Last Year    
Widget B     2          Last Week
Widget C     3          Last Year
Widget C     4          Last Week

我的结果应该只返回小部件A,因为它在最近两个月内没有被订购。它超过一年前被订购的事实并不重要。
小部件C不应出现,因为在过去的两个月中曾下单包含小部件C的订单。
问题是,我想要的记录将没有与之相关的日期范围。换句话说:
我想从Items表中开始,然后排除那些已经有订单并且其中至少一个订单是在2个月范围内下的物品。
如何做到这一点?
1个回答

3

个人认为,这是您问题最清晰的表达:

 SELECT SalesDescription FROM Items I
     WHERE NOT EXISTS (SELECT * FROM Orders O 
                       WHERE O.ItemID = I.ItemID AND O.OrderTime BETWEEN X AND Y)

(其中X和Y是所讨论的日期。)
你也可以这样写:
 SELECT SalesDescription FROM Items 
     WHERE ItemID NOT IN 
           (SELECT ItemID FROM Orders O WHERE O.OrderTime BETWEEN X AND Y)

任一版本对于偶尔使用的几千个项目应该足够快。如果您的项目表更大或需要在某种在线交易期间执行此查询(而不是报告),则有替代的编写方式。您甚至可以使用JOIN来完成,但您只需要加入订单一次,而不是两次。
(注意:您的请求中有两个不同的问题定义。首先,您要求列出在最近两个月内没有销售的所有商品。然后,在摘要中,您要求列出所有已销售至少一次但在过去两个月内未销售的商品。我回答的是第一个版本,它将包括从未出售过的商品。第二个版本则排除它们。)

正在写完全相同的东西。 - dispake
+1 第一个返回了一个空结果集,但第二个做到了我想要的。谢谢! - Nick
这实在令人沮丧,我本来期望它们会有相同的结果。 - Larry Lustig
可能是因为我不得不连接订单和商品表,因为订单表中没有ItemIds? - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接