2013-02-19 2 views
1

У меня такая ситуация. У меня есть таблица Orders, которая связана с OrderStatus.выберите последнюю запись из отношения

OrderStatus

id | orderId | created

Мне нужно, чтобы получить Orders с последнего статуса. Я попробовал этот запрос, чего я не знаю, если он работает. Мне нужно знать, есть ли лучшие решения.

select Orders.id, OrderStatus.status from Orders 
inner join OrderStatus on OrderStatus.id = 
    (select top 1 id from OrderStatus where orderId = Order.id order by created desc) 

ответ

2

Связанный подзапрос - это, как правило, плохая новость (иногда SQL Server может оптимизировать его, иногда он действует как очень медленный цикл). Кроме того, не знаю, почему вы думаете, что нужно DISTINCT, когда вы только принимая последний статус, если вы не имеете любые первичные ключи ...

;WITH x AS 
(
    SELECT o.id, os.status, 
    rn = ROW_NUMBER() OVER (PARTITION BY os.orderId ORDER BY created DESC) 
    FROM dbo.Orders AS o 
    INNER JOIN dbo.OrderStatus AS os 
    ON o.id = os.orderId 
) 
SELECT id, status 
    FROM x 
    WHERE rn = 1; 
+0

Да, я удалил 'distinct'. Код - это выдержка из более длинного запроса, и он проскользнул. Спасибо за объяснение! –

2

Вы можете использовать функцию Row_Number:

WITH CTE AS 
(
    SELECT Orders.id, OrderStatus.status, 
     RN = ROW_NUMBER() OVER (
         PARTITION BY OrderStatus.OrderId 
         ORDER BY created DESC) 
    FROM Orders 
    INNER JOIN OrderStatus ON OrderStatus.OrderId = Orders.id 
) 
SELECT id, status 
FROM CTE WHERE RN = 1 

Я использовал common-table-expression, поскольку она позволяет непосредственно фильтровать и это также очень читаемым.

+0

Теперь у меня есть очень большая проблема, что вы оба обеспечить почти такой же ответ! Думаю, я пойду за ответом Аарона, потому что у него есть интересное объяснение. Спасибо –

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