2010-02-22 183 views
1

我有一个应用程序可以跟踪各种产品的价格。对于任何特定产品,价格在任何一天的任何时间都可能会发生变化,并且不会定期更改。有一个PriceHistory表格记录了产品的所有价格随时间变化的记录。应用程序用户可以选择时间和日期,并查看当时的价格。我使用的是这样的查询,以获得“当前”所有产品的价格在任何给定的日期和时间:MySQL查询在给定日期时间之前获取两条最新记录

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错误,因为我尝试的连接不合法。任何帮助,将不胜感激。

我可以遍历所有的产品,并得到最近的两个价格,但是这需要大约10秒350级的产品75000个的价格行。我不一定需要在一个查询中使用所有产品,但对每个产品运行查询的速度不够快。

回答

2

我会分解成2个选择..

1 - 选择MAX(EffectiveDateTime)......从价格历史记录,其中EffectiveDateTime < = '2010-02-22 12:00:00'

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

部分)抓取所有从上次查询数字PK的,并把它们爆成变量$ ignoreRows

B部分)得到的最大日忽略了最新的一组数据的你想与之比较..即得到第二个到最后一个最新的数据。

选择MAX(EffectiveDateTime)......从价格历史记录,其中EffectiveDateTime < = '2010-02-22 12:00:00' AND priceHistoryID NOT IN($ ignoreRows)

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

0

对该表的查询,按EffectiveDateTime排序,按DESC顺序排列,其中LIMIT 2应该执行此操作。

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

这只会给我两行。我有大约350种产品,所以我正在寻找700行或350行的产品。我编辑了我的问题,使其更清晰一些。 – 2010-02-22 20:43:48

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; 

该临时表现在可以包含每BrandKey 1个或2行,LocationKeyProductKey,然后可以easliy对你的价格表中加入了 - 使用自(左)参加,如果你需要同时包含当前和之前的价格在同一行。

+0

有趣的使用计数器 – Zak 2010-02-23 19:51:45

相关问题