我知道有很多类似的问题。实际上我使用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 :(得分:2)
您有重复的客户名称,因为您链接了orderdate。因此,如果您在某个客户的最后日期有两个或更多订单,您将获得所有这些最后订单。 如果我假设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
答案 1 :(得分: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
答案 2 :(得分: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
它完全符合我的要求。
更新:最好使用OrderID而不是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