我在SQL中遇到COUNT函数问题。我想计算一下客户在2013年下达的订单数量。我遇到的问题是,如果客户在2013年没有下订单,我就无法显示“0”。
我使用的查询如下:
SELECT Customer.CustomerID, Count(Orders.OrderID) AS OrderCount
FROM Customer LEFT JOIN Orders ON Customer.[CustomerID] = Orders.[CustomerID]
WHERE YEAR(Orders.OrderDate)=2013
GROUP BY Customer.CustomerID
ORDER BY Count(Orders.OrderID) DESC , Customer.CompanyName;
为了说明,假设我有一个这样的表:
OrderID OrderYear CustomerID
12 2013 1
15 2013 2
18 2013 1
22 2012 3
我希望我的查询返回的内容是这样的:
CustomerID OrderCount
1 2
2 1
3 0
但我得到的是如下:
CustomerID OrderCount
1 2
2 1
提前谢谢。
答案 0 :(得分:2)
你快到了......
您没有得到没有订单的客户的原因是您在OrderDate
上有条件。
虽然left join
表示即使客户没有订单也应该返回客户,但OrderDate上的条件意味着只返回2013年订单的客户。
要解决这个问题,您所要做的就是为此条件添加另一个选项 - OrderDate
为空。这可以通过简单地将OR Orders.OrderDate IS NULL
添加到where子句来实现:
SELECT Customer.CustomerID, Count(Orders.OrderID) AS OrderCount
FROM Customer LEFT JOIN Orders ON Customer.[CustomerID] = Orders.[CustomerID]
WHERE YEAR(Orders.OrderDate)=2013
OR Orders.OrderDate IS NULL -- Added this row to your query
GROUP BY Customer.CustomerID
ORDER BY Count(Orders.OrderID) DESC , Customer.CompanyName;
<强>更新强>
我的访问时间已经有一段时间了,所以我不确定所有下一个选项是否都适用于访问。
它们都在sql server(you can see the fiddle here)上工作。
选项#1:将OrderDate的条件从where caluse移动到on子句:
SELECT Customer.CustomerID, Count(Orders.OrderID) AS OrderCount
FROM Customer LEFT JOIN Orders ON Customer.[CustomerID] = Orders.[CustomerID]
AND YEAR(Orders.OrderDate)=2013
GROUP BY Customer.CustomerID, Customer.CompanyName
ORDER BY OrderCount DESC, CompanyName;
选项#2:使用派生表仅获取2013年的订单
SELECT Customer.CustomerID, Count(OrderID) AS OrderCount
FROM Customer LEFT JOIN
(
SELECT OrderID, CustomerID
FROM Orders
WHERE YEAR(OrderDate)=2013
) OrdersIn2013
ON Customer.[CustomerID] = OrdersIn2013.[CustomerID]
GROUP BY Customer.CustomerID, Customer.CompanyName
ORDER BY OrderCount DESC, CompanyName;
选项#3 :使用子查询返回订单计数
SELECT Customer.CustomerID,
(SELECT COUNT(OrderId)
FROM Orders
WHERE Orders.CustomerId = Customer.CustomerId
AND YEAR(OrderDate)=2013
) As OrderCount
FROM Customer
ORDER BY OrderCount DESC, CompanyName;
选项#2 是我的个人偏好,但选项#1 可能具有相同的性能和更少的代码,因此有些人认为它是最好的。
选项#3 是最糟糕的,因为它使用的是子查询。