2017-05-08 74 views
1

客户表共有1000个客户,其中1500个订单在2016财年。但是我们想在FY中显示所有客户的订单总数2016年客户是否在该FY下单。但SQL Server 2012中的以下查询仅显示1490.为什么这个左外部连接不包括左边的所有主键

我们在这里可能会丢失什么?

SELECT c.CustomerID, count(*) AS TotalOrders 
FROM Customers c 
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID 
WHERE o.FiscalYear = '2016' 
GROUP BY c.CustomerID 

UPDATE

下面的查询返回只有1次以上的记录(1491) - 还缺9条记录。

SELECT c.CustomerID, count(*) AS TotalOrders 
FROM Customers c 
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID 
        AND o.FiscalYear = '2016' 
GROUP BY c.CustomerID 
+1

where子句在连接后应用。所以连接为没有订单的客户返回空值。但由于这些客户没有订单,因此财务年度不等于2016年,因此记录被排除在外。要更正将外部联接涉及的限制条件移动到联接条件,以便限制与联接一起施加。 – xQbert

+3

您的总记录数应该是1000(客户),总数应该是1500.总和小于1500的唯一可能差异是您已经删除了客户和孤儿订单。或者你的2016年订单1500的数量是错误的开始。 'SELECT * from customer where customerID not in(Select customerID from customers)and FiscalYear ='2016''给你一些记录? – xQbert

+0

是的,我会开始检查像:您的FiscalYear实际上是不同的“2016”的所有记录?有错别字的可能吗?记录如何被标记删除(bit/int标志)? –

回答

6

where子句转动left outer joinInner join

将其更改为AND

SELECT c.CustomerID, count(o.CustomerID) AS TotalOrders 
FROM Customers c 
LEFT JOIN Orders o 
    ON c.CustomerID = o.CustomerID 
    AND o.FiscalYear = '2016'  -- Here 
GROUP BY c.CustomerID 
+0

我应该提到我尝试过在'LEFT JOIN'中加入'Where'条件,但是它只增加了1条记录。仍然缺少9条记录。 – nam

+0

@nam这不是查询。您现在可以检查Customers表中有多少个不同的CustomerID? – GurV

+2

查询中存在另一个错误:对于没有订单的客户,COUNT(*)应该是COUNT(o.CustomerID)或类似的值,以便计数0而不是1。 –

0

正确的SQL是:

SELECT c.CustomerID, count(o.CustomerID) AS TotalOrders, 
     sum(count(o.CustomerID)) over() as TotalTotalOrders 
FROM Customers c LEFT JOIN 
    Orders o 
    ON c.CustomerID = o.CustomerID AND o.FiscalYear = '2016' 
GROUP BY c.CustomerID; 

TotalTotalOrders应该是所有的订单(或至少只是那些有效的客户ID)。

0

这将列出所有客户,无论他们是否有任何订单,无论下订单的年份为。然后sum将计算2016年所有订单,忽略其余,并返回一个整数(即它永远不会为空)。

SELECT 
    c.CustomerID 
    ,sum(case when o.FiscalYear = '2016' then 1 else 0 end) AS TotalOrders 
FROM Customers c 
LEFT JOIN Orders o 
ON c.CustomerID = o.CustomerID 
GROUP BY c.CustomerID 
+0

呃,它的表现不如@ Gurwinder的回答,但是如果您的要求发生变化,它会提供更大的灵活性。 –