Прежде всего, я увидел этот вопрос: SQL MAX столбца, включая его первичный ключ
Мой вопрос отличается тем, что мне нужно больше, чем одна строка, поскольку мне нужны все идентификаторы клиентов.
Я считаю себя компетентным разработчиком SQL, но я имел дело с тайной конструкцией базы данных, над которой я не имею никакого контроля (но я отступаю).
Я ищу более эффективные методы получения первичных ключей строк после фильтра, максимальной агрегации и группировки по.
Я имею дело с версионными таблицами (имеется в виду множество копий одной и той же строки с незначительными изменениями элементов данных до тех пор, пока она не будет «закрыта») Мне нужно получать последний Закрытый (Закрытый = 1) Заказ каждого Клиента каждый день между периодом времени (OrderDateTime) для группы «Заказов», содержащих определенный OrderItem (OrderItem = '1111'). Я не уверен, что я вообще это понимаю. : -)
* Обратите внимание, для краткости и понятности я сделал все возможное, чтобы преобразовать мой вариант использования в общие термины. Orders и OrderItems (поскольку они довольно академичны) вместо того, на что я на самом деле охотюсь.
Традиционно я написал что-то вроде этого.
SELECT
Order.Order_ID
FROM
(
SELECT
Customer_ID,
MAX(OrderedDateTime) AS OrderedDateTime
FROM
Order_versioned
JOIN
OrderItems_versioned
ON Order_versioned.OrderID = OrderItems_versioned.OrderID
AND OrderItem.Item_ID = '1111'
WHERE
Order_versioned.Closed = 1
AND Order_versioned.OrderedDateTime BETWEEN '2012-01-01 00:00:00' AND '2012-01-31 23:59:59'
GROUP BY
Order.Customer_ID
, CAST(Order.OrderedDateTime AS DATE)
) t1
JOIN
Order
ON t1.Customer_ID = Order.Customer_ID
t1.OrderedDateTime = Order.OrderedDateTime
Справочная информация: Customer_ID и OrderedDateTime представляют собой уникальную строку, поэтому я могу присоединиться к ним и быть уверенным, что это одна строка.
Примечание. Для Order_versioned.Closed имеются все индексы и все столбцы * ID.
Проблема заключается в том, что, хотя Order_versioned.Customer_ID индексируется, Order_versioned.OrderedDateTime НЕ индексируется, и я не могу (по многим причинам ... спасибо в поддержку контрактов) добавить индекс. Само собой разумеется, что этот метод занимает некоторое время (только 274 000 000 OrderItems в 20 000 000 заказов).
Я мог бы поиграть с добавлением большего количества полей, которые проиндексированы в моем подзапросе, и добавить их в мое объединение, но в идеале мне нужна новая методология.
Я надеюсь, что у кого-то больше джедаев, чем у меня, есть некоторые черты, которые я не знал об их рукаве и мог указать мне правильное направление. Я думаю, что возможности управления окнами в SQL Server (OVER, PARTITION и т. Д.) Вместе с соответствующей агрегацией могут дать мне то, что мне нужно, я просто недостаточно хорошо знаком с этими новыми функциями (да, я знаю, что они с 2005 года). ). Опять же, это может быть лучшим способом сделать это, учитывая мои ограничения. Я надеюсь, что SQL Server поддерживает какой-то внутренний указатель на запись агрегации MAX, и я просто не знаю, как к ней добраться.
Спасибо за ваше время.