sql - SQL - 列出我们在 1996 年没有进行销售的所有客户
问题描述
这是我的功能性 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
解决方案
我们可以基于您现有的查询并使用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(他的答案是有效的,我赞成)所评论的那样,使用日期比较比依赖日期函数更好的形式性能
推荐阅读
- websocket++ - 在 run() 但在处理程序之外会发生什么?/ send() 应该放在哪里?
- ckan - 防止匿名访问 CKAN 站点的方法
- javascript - 当将在 odoo 中进行销售时,如何向折扣添加限制规则?
- java - 为什么有些方法没有找到,即使已经包含了导入?
- flutter - 无法将 request.auth.id 与 Firestore 规则中的文档 ID 匹配
- jquery - jQuery在每个循环中添加元素
- javascript - 如何将内容添加到 div
- java - 带有拦截器的 Spring Websocket 在连接关闭时执行 preSend
- kubernetes - Kubernetes liveness 探针是否支持使用 PKI 进行用户身份验证?
- android - 如何在不更改“AppTheme”中的“colorAccent”的情况下更改TextInputLayout和光标的浮动标签颜色