2014-02-06 56 views
1

我知道有很多类似的问题。其实我用this,它的工作原理,但我不知道如何包括记录,这在第二个表中没有匹配。加入第二张表中的最后一条记录,但包含记录在第二张表中没有匹配

我在MS SQL Server上使用示例Northwind数据库。

使用此查询:

SELECT Customers.CustomerID, Customers.CompanyName, Orders.OrderID, Orders.OrderDate 
FROM Customers 
LEFT OUTER JOIN Orders 
ON Customers.CustomerID=Orders.CustomerID 
INNER JOIN 
    (
     SELECT CustomerID, MAX(OrderDate) maxDate 
     FROM Orders 
     GROUP BY CustomerID 
    ) b ON Orders.CustomerID = b.CustomerID AND 
      Orders.OrderDate = b.maxDate 
ORDER BY Orders.OrderDate 

我得到正确的结果,但缺少的记录,这不匹配。

如果我使用LEFT OUTER JOIN而不是INNER JOIN:

SELECT Customers.CustomerID, Customers.CompanyName, Orders.OrderID, Orders.OrderDate 
FROM Customers 
LEFT OUTER JOIN Orders 
ON Customers.CustomerID=Orders.CustomerID 
LEFT OUTER JOIN 
    (
     SELECT CustomerID, MAX(OrderDate) maxDate 
     FROM Orders 
     GROUP BY CustomerID 
    ) b ON Orders.CustomerID = b.CustomerID AND 
      Orders.OrderDate = b.maxDate 
ORDER BY Orders.OrderDate 

我得到缺失的记录,但在这种情况下,我已经重复的客户名称。

我想要:只有他最后一个订单的顾客名单,如果他没有订单,他的名字应该出现在任何地方。

+0

您确定您没有使用内部连接获取重复的客户名吗? –

+0

不,没有,只需运行ORDER BY Customers.CustomerID来检查。 – Alexan

+0

它看起来我在这里找到解决方案:http://stackoverflow.com/questions/11764413/join-record-with-most-recent-record-on-second-table?rq=1 – Alexan

回答

2

您重复了客户名称,因为您链接的是订单。因此,如果您在某个客户的最后日期有两个或更多订单,则可以获得所有这些最后的订单。 如果我假设orderid与orderdate具有相同的顺序,那么以下语句应该只为每个客户返回一行。

select cs.*, o.* from customers cs 
left outer join (
    select customerid, max(orderid) as orderid from orders 
    group by customerid 
) lnk on cs.customerid = lnk.customerid 
left outer join orders o on lnk.orderid = o.orderid 
order by cs.customerid 
+0

你是对的OrderID,我在我的查询中做了这些更改。 – Alexan

0

我用这个answer来解决这个问题。

看到代码:

select Customers.CustomerID, Customers.CompanyName, Orders.OrderID, Orders.OrderDate 
from Customers 
left outer join Orders ON Customers.CustomerID=Orders.CustomerID 
where Orders.OrderDate is null OR 
     Orders.OrderDate = 
     (SELECT MAX(OrderDate) 
      FROM Orders 
      WHERE Customers.CustomerID=Orders.CustomerID)  
ORDER BY Customers.CustomerID 

它确实正是我想要的。

UPDATE:这是更好地使用订单ID代替OrderTime:

select Customers.CustomerID, Customers.CompanyName, Orders.OrderID, Orders.OrderDate 
from Customers 
left outer join Orders ON Customers.CustomerID=Orders.CustomerID 
where Orders.OrderID is null OR 
     Orders.OrderID = 
     (SELECT MAX(OrderID) 
      FROM Orders 
      WHERE Customers.CustomerID=Orders.CustomerID)  
ORDER BY Customers.CustomerID 
1

最好的办法,这将是CTE与ROW_NUMBER()此查询将有更好的成本,因为你打Orders表只有一次,而不是两次获取数据并获得最大记录。

WITH LastOrder 
      AS (SELECT CustomerID 
        ,OrderID 
        ,OrderDate 
        ,ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY OrderDate DESC) AS RowNum 
       FROM Orders) 
    SELECT c.CustomerID 
      ,c.CompanyName 
      ,lo.OrderID 
      ,lo.OrderDate 
     FROM Customers AS c 
     LEFT OUTER JOIN LastOrder AS lo 
      ON c.Customer_id = lo.CustomerID 
       AND lo.RowNum = 1 
+0

不,它显示不同订单的重复客户名称 – Alexan

+0

@Alex我必须修复我的“PARTITION BY”子句。需要从中删除'OrderID'。现在它应该只显示最后的顺序。 – 2014-02-07 12:59:11

+0

是的,现在更好,得到正确的结果 – Alexan

相关问题