Получение максимальной и последней строки в SQL - PullRequest
0 голосов
/ 15 марта 2019

У меня есть таблица, содержащая Orders, где в один и тот же день можно создать несколько заказов для данного Name.Мне нужно вернуть последний ордер на указанную дату и имя, и если в этот день для ордера есть несколько ордеров, верните тот, который имеет наибольшее значение ордера.

Пример данных:

  ID  | NAME |  OrderDate   |   OrderValue
  ----+------+--------------+--------------
  1   | A    | 2019-01-15   |   100
  2   | B    | 2019-01-15   |   200
  3   | A    | 2019-01-15   |   150
  4   | C    | 2019-01-17   |   450
  5   | D    | 2019-01-18   |   300
  6   | C    | 2019-01-17   |   500

Возвращаемый результат должен быть:

  ID  | NAME |  OrderDate   |   OrderValue
  ----+------+--------------+--------------
  2   | B    | 2019-01-15   |   200
  3   | A    | 2019-01-15   |   150
  5   | D    | 2019-01-18   |   300
  6   | C    | 2019-01-17   |   500

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

Ответы [ 2 ]

4 голосов
/ 15 марта 2019

Начиная с SQL Server 2005, просто используйте ROW_NUMBER():

SELECT ID, Name, OrderDate, OrderValue
FROM (
    SELECT 
        o.*, 
        ROW_NUMBER() OVER(PARTITION BY Name, OrderDate ORDER BY OrderValue DESC) rn
    FROM orders o
) x WHERE rn = 1

ROW_NUMBER() присваивает ранг каждой записи в группах записей с одинаковыми Name и OrderDate, отсортированными по OrderValue.Запись с наивысшим значением порядка получает номер строки 1.


В более старых версиях решение для фильтрации таблицы заключается в использовании коррелированного подзапроса с условием NOT EXITS:

SELECT ID, Name, OrderDate, OrderValue
FROM orders o
WHERE NOT EXISTS (
    SELECT 1 
    FROM orders o1
    WHERE 
        o1.Name = o.Name 
        AND o1.OrderDate = o.OrderDate 
        AND o1.OrderValue > o.OrderValue
)

Условие NOT EXISTS обеспечивает отсутствие других записей с наибольшим значением OrderValue для тех же Name и OrderDate.

0 голосов
/ 15 марта 2019

Использование cross apply:

select  o.id,  name, orderdate, o.ordervalue
from orders o
cross apply (select top 1 id, ordervalue from orders where name=o.name and orderdate=o.OrderDate order by ordervalue desc) oo
where o.id=oo.id
order by o.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...