【问题标题】:SQL - List all customers that we did not make a sale to in the year 1996SQL - 列出我们在 1996 年没有进行销售的所有客户
【发布时间】:2019-11-23 05:09:29
【问题描述】:

这是我在 1996 年返回客户的有效 SQL 查询:

   SELECT C.CustomerID, C.CompanyName
   FROM Customers C, Orders O
   WHERE C.CustomerID = O.CustomerID AND YEAR(O.OrderDate) = 1996
   GROUP BY C.CustomerID, C.CompanyName
   ORDER BY C.CustomerID

现在我试图展示相反的情况;退回我们在 1996 年没有销售给的所有客户(即使我们在其他年份确实向他们销售过)。这就是我所拥有的,但它既返回了我们在 1996 年没有销售给的客户,也返回了我们做过的客户:

SELECT C.CustomerID, C.CompanyName FROM Orders O JOIN Customers C
ON O.CustomerID = C.CustomerID 
WHERE YEAR(O.OrderDate) != 1996
GROUP BY C.CustomerID, C.CompanyName
ORDER BY C.CustomerID

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。

标签: sql datetime subquery left-join


【解决方案1】:

您可以使用相关子查询来获取具有NOT EXISTS 的客户从 1996 年开始的订单。

SELECT c.customerid,
       c.companyname
       FROM customers c
       WHERE NOT EXISTS (SELECT *
                                FROM orders o
                                WHERE o.customerid = c.customerid
                                      AND o.orderdate >= '1996-01-01'
                                      AND o.orderdate < '1997-01-01');

请注意,您最好不要在orderdate 上使用year(),因为这会阻止使用索引表单,从而减慢查询速度。

【讨论】:

    【解决方案2】:

    我们可以基于您现有的查询并使用left join 反模式:

    SELECT C.CustomerID, C.CompanyName
    FROM Customers C
    LEFT JOIN Orders O
        ON  C.CustomerID = O.CustomerID 
        AND O.OrderDate >= '1996-01-01'
        AND O.OrderDate <  '1997-01-01'
    WHERE O.CustomerID IS NULL
    ORDER BY C.CustomerID
    

    这句话为:尝试将每个客户与他们在 1996 年下的订单联系起来,并过滤那些没有任何订单的客户。

    旁注:

    • 始终使用显式标准连接(使用 ON 关键字);应该避免老式的隐式连接(FROM 子句中没有逗号)

    • 正如sticky bit 所评论的(他的答案是有效的,我赞成),使用日期比较比依赖日期函数更好的表单性能

    【讨论】:

      【解决方案3】:

      试试这个

      SELECT C.CustomerID, C.CompanyName FROM Customers C
      WHERE 
      not exists(select 1 FROM Orders O where O.CustomerID = C.CustomerID and YEAR(O.OrderDate) = 1996)
      ORDER BY C.CustomerID
      

      【讨论】:

        猜你喜欢
        • 2020-10-31
        • 2021-03-23
        • 1970-01-01
        • 2022-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多