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

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

OrderID CustomerID  OrderDate   LocationID          
1       4           1/1/2001    1001
2       4           1/2/2001    1003
3       4           1/3/2001    1001
4       5           1/4/2001    1001
5       5           1/5/2001    1001
6       5           1/6/2001    1003
7       5           1/7/2001    1002
8       5           1/8/2001    1003
9       5           1/8/2001    1002

Группируя по CustomerID, я хочу получить максимальное OrderDate, а затем LocationID, связанное с максимальным OrderDate. Если есть несколько записей с общей максимальной датой заказа, тогда возьмите LocationID, связанный с максимальным OrderID, из тех записей с максимальной датой.

Окончательный набор данных должен выглядеть так:

CustomerID  OrderDate   LocationID      
4           1/3/2001    1001
5           1/8/2001    1002

Я пытался написать запрос с большим количеством вложенных подзапросов и уродливых соединений, но на самом деле я ничего не получаю. Какой SQL мне нужно написать, чтобы помочь мне получить этот результат.


person Ben McCormack    schedule 22.01.2011    source источник


Ответы (2)


SELECT
   C.Name,
   C.CustomerID,
   X.*
FROM
   Customers C
   CROSS APPLY (
      SELECT TOP 1 OrderDate, LocationID
      FROM Orders O
      WHERE C.CustomerID = O.CustomerID
      ORDER BY OrderDate Desc, OrderID Desc
   ) X

Если вы извлечете какие-либо столбцы из таблицы «Клиенты», это, вероятно, превзойдет другие методы.

Если нет, то ответ Row_Number, вытягивающий только из Приказов, вероятно, будет лучшим. Но если вы каким-либо образом ограничиваете Заказчика, то CROSS APPLY снова будет лучшим. Возможно с большим отрывом.

person ErikE    schedule 22.01.2011

Хитрость заключается в том, чтобы использовать подзапрос как значение, а не как соединение:

select customerId,orderDate,locationId
  from orders o1
 where orderDate = (
           select top 1 orderdate
             from orders o2
            where o1.customerId = o2.customerId
            order by orderdate desc
       )
person Ken Downs    schedule 22.01.2011