2010-02-22 100 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

相關問題