2014-02-06 2 views
1

Я знаю, что есть много подобных вопросов. Фактически я использовал this, и он работает, но я не могу понять, как включить записи, которые не совпадают во второй таблице.присоединяйтесь только к последней записи во второй таблице, но включите записи во второй таблице

Я использую образец Northwind db на MS SQL Server.

С помощью этого запроса:

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

У вас есть повторные имена клиентов, потому что вы связываете их по заказу. Поэтому, если у вас есть два или более заказов на последнюю дату для какого-то клиента, вы получаете все эти последние заказы. Если я предполагаю, что заказ имеет ту же последовательность, что и 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: Это лучше использовать 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 
1

Лучший способ сделать это было бы КТР с 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'. теперь он должен показывать только последний заказ. –

+0

да, теперь лучше, получите правильный результат – Alexan

Смежные вопросы