MySQL查询在给定的DateTime之前获取两个最新记录

时间:2010-02-22 20:28:27

标签: sql mysql

我有一个跟踪各种产品价格的应用程序。在任何一天的任何时间,任何特定产品的价格可能会发生变化,并且不会定期更改。有一个PriceHistory表,其中记录了产品随时间推移的所有价格。该应用程序的用户可以选择时间和日期,并查看当时的价格。我使用这样的查询来获取所有产品在任何特定日期和时间的“当前”价格:

SELECT A.*
FROM `PriceHistory` A
INNER JOIN (
    SELECT `BrandKey`, `LocationKey`, `ProductKey`, max(`EffectiveDateTime`) AS MaxUpdateDate
    FROM `PriceHistory`
    WHERE `EffectiveDateTime` <= '2010-02-22 12:00:00'
    GROUP BY `BrandKey`, `LocationKey`, `ProductKey`
) AS B ON 
A.`BrandKey` = B.`BrandKey`
AND A.`LocationKey` = B.`LocationKey`
AND A.`ProductKey` = B.`ProductKey`
AND A.`EffectiveDateTime` = B.MaxUpdateDate

现在我需要能够向用户显示当价格生效时价格变化了多少。因此,我需要在选定的时间内获得两个最近的价格而不是一个。我很难过。我尝试了几件事情,我只是因为我的尝试加入不合法而得到SQL错误。任何帮助将不胜感激。

我可以遍历所有产品并获得最近的两个价格,但350个产品和75,000个价格行需要大约10秒钟。我不一定在一个查询中需要所有产品,但是对每个产品运行查询的速度还不够快。

3 个答案:

答案 0 :(得分:2)

我会把它分成两个选择..

1st - 从价格历史中选择最高(EffectiveDateTime)... EffectiveDateTime&lt; ='2010-02-22 12:00:00'

步骤2)这要求priceHistory表中有一个数字(autoinc类型)PK。如果它不存在则添加它。假设此列名为PriceHistoryID

部分a)从上一个查询中获取所有数字PK,并将它们内爆到var $ ignoreRows

部分b)获取最大日期,忽略您要对其进行差异的最新数据集。即获取倒数第二个最新数据。

EffectiveDateTime&lt; ='2010-02-22 12:00:00'和priceHistoryID NOT IN($ ignoreRows)

注意,如果您在价格历史记录中只有1个数据点,那么它可能不匹配1-1,但这是一个相对较小的事情,您可以在代码中修复,我会想象......

答案 1 :(得分:1)

如果将auto_increment列定义为组合键的最后一个组件,则该列将充当具有相同值的所有行的计数器。

EG。

v1,v2,v3,1
v1,v2,v3,2
v1,v2,v4,1
...

您可以在从历史记录表构建的临时表中使用此功能,以按降序日期值对具有相同BrandKey,LocationKey,ProductKey的所有条目进行排名。

create temporary table ph ( 
    `BrandKey` varchar(10),
    `LocationKey` varchar(10), 
    `ProductKey` varchar(10), 
    `EffectiveDateTime`datetime,
    rank int not null auto_increment,
    primary key(BrandKey, LocationKey, ProductKey, rank);

insert into ph
   select `BrandKey`, `LocationKey`, `ProductKey`, `EffectiveDateTime`, NULL
   FROM `PriceHistory`
   WHERE `EffectiveDateTime` <= '2010-02-22 12:00:00'
   order by EffectiveDateTime desc;

delete from ph where rank > 2;

此临时表现在每BrandKeyLocationKeyProductKey包含1或2行,然后可以使用自我(左)联接轻松加入Price表如果您需要在同一行中包含当前和之前的价格。

答案 2 :(得分:0)

针对该表的查询,按EffectiveDateTime顺序排列DESCLIMIT 2,应该这样做。

SELECT A.*
FROM `PriceHistory` A
WHERE <clauses for selecting a product and brand go here>
ORDER BY `EffectiveDateTime` DESC
LIMIT 2