SQL-列出所有我们在1996年没有销售的客户

时间:2019-11-23 05:09:29

标签: sql

这是我正常使用的SQL查询,用于返回我们在1996年出售给的客户:

   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

3 个答案:

答案 0 :(得分: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');

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

答案 1 :(得分:1)

我们可以基于您现有的查询并使用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子句中不要使用逗号)

  • 也用粘性位(其答案是有效的,我对此表示反对)评​​论说,使用日期比较比依赖日期函数要好表格性能

答案 2 :(得分:0)

尝试

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
相关问题