首先,我看到了这个问题:SQL MAX of column including its primary key 我的问题不同,因为我需要多于一行,因为我需要所有客户ID。我认为自己是一个有能力的SQL开发人员,但我一直在处理一个我无法控制的神秘数据库设计(但我离题了)。SQL Server - MAX时间戳记行的主键由客户和时间戳分组
我正在寻找更多的performant方法来获取过滤器,最大聚合和组之后的主键行。
我正在处理版本化表格(意味着许多副本的同一行与次要数据元素更改,直到它“关闭”)。对于包含特定OrderItem(OrderItem ='1111')的一组“订单”,我需要每天在每个客户的一个时间段(OrderDateTime)之间获得最近的Closed(Closed = 1)订单。我不确定我是否理解这一点。 :-)
*请注意,为了简洁和易于理解,我尽我所能将我的用例转换为通用术语。订单和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未被编入索引,并且我无法(由于很多原因...感谢您支持合同)添加索引。不用说这种方法需要一段时间(20,000,000个订单中只有274,000,000个订单项)。
我可以在添加更多在我的子查询中编入索引的字段并将其添加到我的连接中,但理想情况下,我需要一种新的方法。
我希望有人比我拥有更多的绝地武器,但是我不知道他们的袖子,可以指引我朝着正确的方向发展。我认为SQL Server的窗口化功能(OVER,PARTITION等)以及适当的聚合可能会让我得到我需要的东西,但我对这些新功能不够熟悉(是的,我知道它们来自2005年)。然后,再次,这可能是考虑到我的限制,最好的方法。我所希望的是,SQL Server在MAX聚合中维护某种内部指针,并且我不知道如何去实现它。
感谢您的时间。