2012-10-21 57 views
5

tôi có thể sử dụng một số giúp đỡ (tốt nhất là hướng dẫn của một dummy) để cập nhật bảng sau:Tính toán và bảng cập nhật với SMA của giá cổ phiếu đóng cửa ở 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; 

Cột moving_average trống bây giờ. Tất cả các cột khác được phổ biến (trong thời gian này, tôi ổn với điều này là "tĩnh", nó không cần cập nhật khi tôi thêm hàng - mặc dù nếu điều này dễ làm, điều đó sẽ rất tuyệt). Đây là mức trung bình 20 ngày mà tôi hy vọng sẽ tính toán.

Tôi đã thử bằng cách thực hiện các bước ở đây đến hết khả năng của tôi:

How do I calculate a moving average using MySQL?

truy vấn của tôi là thế này:

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 

Có tôi sửa đổi các truy vấn một cách chính xác? Cần phải làm gì để viết kết quả vào cột moving_average?

Khi tôi chạy ở trên, không có gì xảy ra (nó nói nó đang chạy, không có lỗi, sau khi để nó chạy trong một thời gian dài tôi vừa dừng lại). Cột moving_average vẫn có giá trị NULL.

Tôi cũng nhìn câu trả lời này: How to calculated multiple moving average in MySQL

Tuy nhiên, tôi không chắc chắn những gì tôi cần phải thay đổi câu trả lời cho bàn của tôi.

Mọi trợ giúp đều được đánh giá cao.

+2

Tuyên bố bạn đã đăng không có thông báo cập nhật trong đó. Chỉ cần một lựa chọn. Đương nhiên, điều này có nghĩa là không có gì sẽ được cập nhật. – SchmitzIT

Trả lời

2

Có hai cách để làm điều này:

  1. Tạo một truy vấn update rằng cập nhật mỗi hàng trong bảng của bạn
  2. Tạo một thủ tục lưu trữ mà không được công việc

Cá nhân tôi thích lựa chọn 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

Cảm ơn Barranka - Tôi đã sao chép và dán và cố gắng chạy nó. Kết quả là "Truy vấn trống". Tôi cũng đã "hiển thị trạng thái thủ tục" và nó trống. Tôi có nên sửa đổi thêm? Dù bằng cách nào, cảm ơn bạn đã giúp đỡ! – gcubed

+0

@ user1644609 bạn có thể cần phải kiểm tra xem tôi đã viết mọi thứ đúng chưa (tôi nghĩ rằng tôi đã không làm hỏng, nhưng luôn có cơ hội tôi bị mất một cái gì đó), và sau đó kiểm tra bảng của bạn ... là những tính toán chính xác? – Barranka

+0

Tôi đã cố gắng để "gỡ lỗi" nó, nhưng thành thật không biết liệu nó chính xác hay không. Tôi đã chơi xung quanh với nó một chút (và sẽ tiếp tục) nhưng đã không thể tạo ra các thủ tục được lưu trữ, cũng không cư trú ngày vào cột moving_average. Nhưng cảm ơn bạn đã đưa tôi vào một ca khúc. – gcubed

0

Đây là giải pháp có thể có:

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 

Xin lỗi tôi không sử dụng mysql, vì vậy tôi đoán về cú pháp số học ngày. Và tôi đã thêm điều kiện để chỉ cập nhật các hàng trong đó moving_average của bạn không có giá trị.

CẬP NHẬT: Đảm bảo bạn hiểu rằng giải pháp này dựa trên lịch 365 ngày. Hầu hết các thị trường chứng khoán trung bình như "20 ngày" hoặc "30 ngày" được dựa trên lịch giao dịch không bao gồm ngày cuối tuần và ngày lễ. Bạn sẽ cần phải tạo một bảng lịch giao dịch của bạn (một danh sách đơn giản của tất cả các ngày giao dịch). Nếu bạn muốn làm điều đó, bạn có thể muốn đặt một câu hỏi mới cho hiệu ứng đó.

Các vấn đề liên quan