2012-05-02 46 views
1

我正在研究彙總財務數據觀察的數據庫(以貨幣對USDCAD爲例)。正常化MySQL數據的日期時間

財務數據作爲觀察值發佈。數據提供者確定的觀測日期和時間並未設置。

我的表是這樣的:當我需要在同一時間獲得該系列的價值在沒有具體觀測 CREATE TABLE observations (symbol varchar(32) not null, datetime datetime not null, value decimal(20, 10) not null);

,就會出現問題。例如,我可能想要在10:30:15上午重新安排我們以加拿大元出售的某種產品。

但是,我可能完全沒有10:30:15 am的USDCAD觀察。這將需要我做一個加權平均值,以在那個確切的時間進行觀察。

這有點麻煩,但可能。更大的問題是 - 如果我有一個每秒鐘包含我們產品的美元價格的表格,並且我想在USDCAD中對每個產品價格觀察值(每秒)進行重新報價(在有隨機時間觀察的情況下),我不能想想一個沒有瘋狂的子查詢的方法。

這裏我最好的選擇是什麼?插入值時,是否還可以更好地計算USDCAD系列的每秒觀察值?

+0

如何使用在使用MySQL的TIME(你列) –

+0

條件好端端的一個時間範圍 - 不知道到底怎麼說解決了這個問題。我如何用TIME(列)實現加權平均? – user1094786

+0

你到目前爲止嘗試過什麼?如果你寫了任何查詢,請把它提出來,所以我們可以看到我們如何解決它 –

回答

3
  1. 通過應用linear interpolation獲取在@time加權平均觀察:

    CREATE VIEW `productsCAD` AS 
        SELECT `products`.* 
        , `products`.`price` * `exchange`.`value` AS `priceCAD` 
        FROM `products` 
        , (
         SELECT `value` 
         FROM  `observations` 
         ORDER BY `datetime` DESC 
         LIMIT 1 
        ) AS `exchange`; 
    

SELECT p0.y + (UNIX_TIMESTAMP(@time)-p0.x) * (p1.y-p0.y)/(p1.x-p0.x) 
FROM 
    (
    SELECT `value`      AS y 
     ,  UNIX_TIMESTAMP(`datetime`) AS x 
    FROM  `observations` 
    WHERE `datetime` <= @time 
    ORDER BY `datetime` DESC 
    LIMIT 1 
) p0, 
    (
    SELECT `value`      AS y 
     ,  UNIX_TIMESTAMP(`datetime`) AS x 
    FROM  `observations` 
    WHERE `datetime` >= @time 
    ORDER BY `datetime` ASC 
    LIMIT 1 
) p1; 
  • 採用最新匯率CAD價格創建你的產品VIEW

    UPDATE

    以獲得多個預定義的時間內插的價格(假定爲存儲在一個名爲名爲times表內timeDATETIME值),則需要使用子查詢首先獲得的時間立即之前和緊接以下意見再加入那些與觀測表再次得到相應的價值是:如果你想在查詢中指定所需的時間

    SELECT time, p0.y + IFNULL((unixtime-p0.x) * (p1.y-p0.y)/(p1.x-p0.x), 0) AS value 
    FROM 
        (
        SELECT 
          time, 
          UNIX_TIMESTAMP(`time`)    AS `unixtime`, 
         MAX(UNIX_TIMESTAMP(`before`.`datetime`)) AS `prevTime`, 
         MIN(UNIX_TIMESTAMP(`after`.`datetime`)) AS `nextTime` 
        FROM 
         `times` 
         JOIN (SELECT `datetime` FROM `observations`) 
         AS `before` ON (`before`.`datetime` <= `time`) 
         JOIN (SELECT `datetime` FROM `observations`) 
         AS `after` ON (`after`.`datetime` >= `time`) 
        GROUP BY `time` 
    ) AS `matches` 
        JOIN (
        SELECT 
         UNIX_TIMESTAMP(`datetime`) AS x, 
         `value`     AS y 
        FROM `observations` 
    ) AS p0 ON (p0.x = `matches`.`prevTime`) 
        JOIN (
        SELECT 
         UNIX_TIMESTAMP(`datetime`) AS x, 
         `value`     AS y 
        FROM `observations` 
    ) AS p1 ON (p1.x = `matches`.`nextTime`); 
    

    (而不是使用預定義的表格times),動態使用UNION替換與建立這樣一個表的子查詢中引用times

    SELECT time, p0.y + IFNULL((unixtime-p0.x) * (p1.y-p0.y)/(p1.x-p0.x), 0) AS value 
    FROM 
        (
        SELECT 
          time, 
          UNIX_TIMESTAMP(`time`)    AS `unixtime`, 
         MAX(UNIX_TIMESTAMP(`before`.`datetime`)) AS `prevTime`, 
         MIN(UNIX_TIMESTAMP(`after`.`datetime`)) AS `nextTime` 
        FROM 
         (
            SELECT '2012-05-02 19:20:00' AS `time` 
         UNION ALL SELECT '2012-05-02 19:20:05' 
         UNION ALL SELECT '2012-05-02 19:20:10' 
         UNION ALL SELECT '2012-05-02 19:20:15' 
         -- etc. 
        ) AS `times` 
         JOIN (SELECT `datetime` FROM `observations`) 
         AS `before` ON (`before`.`datetime` <= `time`) 
         JOIN (SELECT `datetime` FROM `observations`) 
         AS `after` ON (`after`.`datetime` >= `time`) 
        GROUP BY `time` 
    ) AS `matches` 
        JOIN (
        SELECT 
         UNIX_TIMESTAMP(`datetime`) AS x, 
         `value`     AS y 
        FROM `observations` 
    ) AS p0 ON (p0.x = `matches`.`prevTime`) 
        JOIN (
        SELECT 
         UNIX_TIMESTAMP(`datetime`) AS x, 
         `value`     AS y 
        FROM `observations` 
    ) AS p1 ON (p1.x = `matches`.`nextTime`); 
    
  • +0

    非常感謝你。我真的很喜歡1),這非常清楚,非常有幫助!唯一的補充是,我今天發現我需要對數據進行線性插值,而不管重新定價的事情。例如,假設我在1:04,1:12,1:17,1:21和1:27具有隨機分散的觀測值 - 我需要將數據顯示爲具有1:00,1:05,1的觀測值:10,1:15,1:20,1:25,1:30,並插入相應的數據。你的查詢完全是這樣的,但只是一個值。有一種方法可以在一個查詢中爲多個值執行此操作嗎?再次感謝。 – user1094786

    +0

    @ user1094786:查看我上面更新的答案。 – eggyal

    +0

    再次感謝你!你的查詢很好地工作。只有一件事我無法弄清楚,其原因是我簡化了我的問題。在我的觀察表中,我有一個名爲series_id的列。這表明該觀測屬於哪個系列,並且該系統對該表中的不同系列有很多觀察結果。我只需要在一個系列上執行上述操作,所以我嘗試在JOIN的所有ON子句中添加AND series_id = ID,但查詢只是永遠運行並且永遠不會返回。目前,我在表中有30,000個觀察值。我究竟做錯了什麼? – user1094786