T-SQL | Применение оператора OVER (PARTITION BY)

Если агрегировать данные с помощью оператора OVER (PARTITION BY) вместо GROUP BY, то результат запроса будет тот же, а SQL-код проще (на больших объемах данных отрабатывает быстрее).

 

Например, есть таблица по заказам клиентов – SalesOrderHeader (пример построен по данным таблицы SalesOrderHeader базы данных AdventureWorks):

 

 

С помощью SQL-запроса требуется определить по каждому клиенту последний заказ в виде:

 

ID клиента

– CustomerID

Дата последнего заказа

– LastOrderDate

ID этого заказа

– SalesOrderID

 

Решение задачи с помощью группировки GROUP BY

 

Как вариант, подзапросом определяем максимальную дату заказа (MAX(OrderDate) AS LastOrderDate) по клиентам (GROUP BY CustomerID), затем по соответствующей связи (CustomerID, OrderDate, LastOrderDate) находим ID этого заказа (SalesOrderID):

 


USE AdventureWorks

GO

SELECT    

sales_order_list.CustomerID,

last_order_list.LastOrderDate,

sales_order_list.SalesOrderID

FROM        

 (SELECT    

 CustomerID,

 OrderDate,

 SalesOrderID,

 SalesOrderNumber

         FROM Sales.SalesOrderHeader) AS sales_order_list

 INNER JOIN (SELECT CustomerID,

                         MAX(OrderDate) AS LastOrderDate

                         FROM Sales.SalesOrderHeader

                             GROUP BY CustomerID

                 ) AS last_order_list

 ON sales_order_list.CustomerID = last_order_list.CustomerID

 AND sales_order_list.OrderDate = last_order_list.LastOrderDate


 

Графический вид запроса и результат возвращаемых данных:

 

 

 

Решение задачи с помощью группировки OVER (PARTITION BY)

 

Подзапросом определяем максимальную дату заказа (MAX(OrderDate) AS LastOrderDate) по клиентам (Over (Partition BY CustomerID)), затем по соответствующей связи (OrderDate, LastOrderDate) находим ID этого заказа (SalesOrderID):

 


USE AdventureWorks

GO

SELECT

 last_order.CustomerID,

 last_order.LastOrderDate,

 last_order.SalesOrderID

FROM

(SELECT

 CustomerID,

         SalesOrderID,

 OrderDate,

         MAX(OrderDate) Over (Partition BY CustomerID) AS LastOrderDate

FROM Sales.SalesOrderHeader

)last_order

WHERE last_order.LastOrderDate = last_order.OrderDate

 


 

Результат возвращаемых данных:

 

 



© 2018 | Анна Петросян | pashelp@yandex.ru