T-SQL | Применение оператора OVER (PARTITION BY) |
Если агрегировать данные с помощью оператора OVER (PARTITION BY) вместо GROUP BY, то результат запроса будет тот же, а SQL-код проще (на больших объемах данных отрабатывает быстрее).
Например, есть таблица по заказам клиентов – SalesOrderHeader (пример построен по данным таблицы SalesOrderHeader базы данных AdventureWorks):
С помощью SQL-запроса требуется определить по каждому клиенту последний заказ в виде:
Решение задачи с помощью группировки 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
Результат возвращаемых данных:
|