我有一个表格,其中包含MS SQL 2005表格中许多不同"事物"的价格.每件事每天有数百条记录,不同的东西在不同的时间获得价格更新.
ID uniqueidentifier not null, ThingID int NOT NULL, PriceDateTime datetime NOT NULL, Price decimal(18,4) NOT NULL
我需要获得今天最新的一组价格.下面的查询有效但我收到了数百行,我必须循环它们,并且每个ThingID只提取最新的一行.我怎样才能(例如通过GROUP BY)说我想要每个ThingID最新的一个?或者我必须使用子查询?
SELECT * FROM Thing WHERE ThingID IN (1,2,3,4,5,6) AND PriceDate > cast( convert(varchar(20), getdate(), 106) as DateTime)
更新:为了隐藏复杂性,我将ID列放在一个int中.在现实生活中它是GUID(而不是顺序类).我已经更新了上面的表def以使用uniqueidentifier.
我认为表结构的唯一解决方案是使用子查询:
SELECT * FROM Thing WHERE ID IN (SELECT max(ID) FROM Thing WHERE ThingID IN (1,2,3,4) GROUP BY ThingID)
(鉴于最高ID也意味着最新价格)
但是我建议你添加一个"IsCurrent"列,如果它不是最新价格,则为0,如果是最新价格则为1.这将增加数据不一致的可能风险,但是当表变大时(如果它在索引中),它将大大加快整个过程.那么你需要做的就是......
SELECT * FROM Thing WHERE ThingID IN (1,2,3,4) AND IsCurrent = 1
UPDATE
好的,Markus更新了问题,表明ID是唯一的ID,而不是int.这使得编写查询变得更加复杂.
SELECT T.* FROM Thing T JOIN (SELECT ThingID, max(PriceDateTime) WHERE ThingID IN (1,2,3,4) GROUP BY ThingID) X ON X.ThingID = T.ThingID AND X.PriceDateTime = T.PriceDateTime WHERE ThingID IN (1,2,3,4)
我真的建议使用"IsCurrent"列或者使用答案中的其他建议并使用"当前价格"表和单独的"价格历史"表(最终会是最快的,因为它保持价格表本身很小).
(我知道底部的ThingID是多余的.只要尝试使用或不使用"WHERE"就更快.不确定优化器完成其工作后哪个版本会更快.)