SQL查询获取最新价格

标签 sql sql-server sql-server-2005

我有一个表,其中包含 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(而不是顺序类型)。我已更新上面的表定义以使用 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

更新

好的,Markus 更新了问题以表明 ID 是 uniqueid,而不是 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”会更快。不确定优化器完成工作后哪个版本会更快。)

关于SQL查询获取最新价格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49404/

相关文章:

sql - 为什么这个(不相关的)子查询会导致这样的问题?

php - 如何在html表中打印具有 "one to many"关系的两个表的列?

c# - 将 Android 应用程序连接到 SQL Server

sql-server - SQL 2005 发布者和 SQL 2008 订阅者之间可以进行复制吗?

sql - SQL Server 中的字母系列生成

sql - SQL Server 2005中的CHECKSUM()冲突

mysql - 我的代码显示错误的排名值

sql - SQL中如何去除字符串中的重复项

mysql - SQL 脚本创建存储过程 - 导入错误

sql - 创建全局声明