我有一个跟踪各种产品价格的应用程序。在任何一天的任何时间,任何特定产品的价格可能会发生变化,并且不会定期更改。有一个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秒钟。我不一定在一个查询中需要所有产品,但是对每个产品运行查询的速度还不够快。
答案 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;
此临时表现在每BrandKey
,LocationKey
,ProductKey
包含1或2行,然后可以使用自我(左)联接轻松加入Price表如果您需要在同一行中包含当前和之前的价格。
答案 2 :(得分: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