2012-10-21 80 views
5

我可以利用一些幫助(最好是假人的指南)爲下表更新簡單移動平均線收盤價格更新表:計算並與MYSQL

CREATE TABLE `SYMBOL` (
    `day` date NOT NULL, 
    `open` decimal(8,3) DEFAULT NULL, 
    `high` decimal(8,3) DEFAULT NULL, 
    `low` decimal(8,3) DEFAULT NULL, 
    `close` decimal(8,3) DEFAULT NULL, 
    `volume` bigint(20) DEFAULT NULL, 
    `adj_close` decimal(8,3) DEFAULT NULL, 
    `moving_average` decimal(8,3) DEFAULT NULL, 
    PRIMARY KEY (`day`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

的MOVING_AVERAGE列現在是空的。所有其他列都被填充(目前,我確定這是「靜態」,它不需要更新,因爲我添加了行 - 儘管如果這很容易做到,那就太棒了)。這是我希望計算的20日移動平均線。

How do I calculate a moving average using MySQL?

我的查詢是這樣的:

我已經在這裏進行的步驟,將盡我所能試圖

SELECT 
    `close`, 
    (
    SELECT 
      AVG(`close`) AS moving_average 
    FROM 
      SYMBOL T2 
    WHERE 
      (
       SELECT 
        COUNT(*) 
       FROM 
        SYMBOL T3 
       WHERE 
        `day` BETWEEN T2.day AND T1.day 
     ) BETWEEN 1 AND 20 
    ) 
FROM 
    SYMBOL T1 

有我修改正確的查詢?將結果寫入move_average列需要做什麼?

當我運行上述,沒有任何反應(它說,它的運行,沒有錯誤,讓它運行很長一段時間,我剛剛停止它)。列moving_average仍然具有NULL值。

我也看了這樣的回答: How to calculated multiple moving average in MySQL

不過,我不能確定我需要改變我的表的答覆。

任何幫助表示讚賞。

+2

您發佈的聲明中沒有更新聲明。只是一個選擇。當然,這意味着什麼都不會得到更新。 – SchmitzIT

回答

2

這樣做有兩種方式:

  1. 創建一個update查詢您的表更新中的每一行
  2. 創建一個存儲過程,沒有工作

我個人比較喜歡的選擇2:

delimiter $$ 
create procedure movingAvg() 
begin 
    declare mv double; 
    declare t date; 
    declare done int default false; 
    declare cur_t cursor for 
     select distinct day from symbol 
     order by day; 
    declare cur_mv cursor for 
     select avg(close) from symbol 
     where day between date_add(t, interval -19 day) and t; 
     -- Here you define the interval of your MV. 
     -- If you want a 20-day MV, then the interval is between t-19 and t 
    declare continue handler for not found set done=true; 

    open cur_t; 
    loop_day: loop 
     fetch cur_t into t; 
     if not done then 
      open cur_mv; 
      fetch cur_mv into mv; 
      close cur_mv; 
      update SYMBOL 
       set moving_average = mv 
       where day=t; 
     else 
      leave loop_day; 
     end if; 
    end loop loop_day; 
    close cur_t; 
end; 
delimiter ; 
+0

感謝Barranka - 我複製並粘貼這個並試圖運行它。結果是「查詢是空的」。我也做了「顯示程序狀態」,它是空的。我應該進一步修改嗎?無論哪種方式,謝謝你的幫助! – gcubed

+0

@ user1644609你可能需要檢查我寫的東西是否正確(我認爲我沒有搞砸,但總有機會我錯過了一些東西),然後檢查你的桌子......計算是否正確? – Barranka

+0

我試圖「調試」它,但老實說不知道它的正確與否。我已經玩了一些(並將繼續),但一直未能創建存儲過程,也沒有將日期填充到moving_average列中。但是,謝謝你讓我走上了一條軌道。 – gcubed

0

這裏是一個可能的解決方案:

update SYMBOLS 
from (
    select a.day 
     , avg(b.close) as moving_average 
    from SYMBOLS a 
    cross join SYMBOLS b 
    where b.day BETWEEN date_sub(a.day, INTERVAL 19 DAY) and a.day 
     and a.moving_average is null 
    group by a.day 
    ) x 
set moving_average=x.moving_average 
where SYMBOLS.day=x.day 

對不起,我不使用mysql自己,所以我猜測日期算術語法。我添加了一個條件,只更新您的moving_average爲空的行。

更新:請確保您瞭解此解決方案基於365天的日曆。大多數股票市場平均數據如「20日」或「30日」均基於不包括週末和假日的交易日曆。您需要自行創建交易日曆表(所有交易日期的簡單列表)。如果你想這樣做,你可能想問一個新的問題。