2009-05-18 10 views

Odpowiedz

18

To jest tuż poza moją głową, a ja wychodzę z drzwi, więc nie sprawdzono. Nie mogę też sobie wyobrazić, że byłby bardzo dobry na każdym dużym zbiorze danych. Potwierdziłem, że przynajmniej działa bez błędu. :)

SELECT 
    value_column1, 
    (
    SELECT 
      AVG(value_column1) AS moving_average 
    FROM 
      Table1 T2 
    WHERE 
      (
       SELECT 
        COUNT(*) 
       FROM 
        Table1 T3 
       WHERE 
        date_column1 BETWEEN T2.date_column1 AND T1.date_column1 
     ) BETWEEN 1 AND 20 
    ) 
FROM 
    Table1 T1 
1

Kiedy miałem podobny problem, skończyło się na używaniu tabel tymczasowych z różnych powodów, ale dzięki temu było o wiele łatwiej! To, co zrobiłem, wygląda bardzo podobnie do tego, co robisz, jeśli idzie o schemat.

Utwórz schemat podobny do identyfikatora tożsamości, daty początkowej, daty zakończenia, wartości. Po wybraniu dokonaj subselectu avg z poprzednich 20 na podstawie identyfikatora tożsamości.

Wykonuj to tylko, jeśli już używasz tabel tymczasowych z innych powodów (wielokrotnie uderzałem w te same wiersze dla różnych danych, więc pomocne było posiadanie małego zestawu danych).

+0

Nie jestem pewien, gdzie pojawiają się tymczasowe tabele, mogę bez nich korzystać z twojego rozwiązania. Chociaż problem polega na tym, że kolumna tożsamości jest ciągła. –

+0

Kolumna tożsamości sąsiadująca jest rodzajem całego punktu tabeli tymczasowej ..... W moim przypadku mam dane lat i lat, ale każdy miesiąc danych jest przetwarzany osobno. Wyodrębniam dane do tabel tymczasowych i wykonuję na nich wiele pomiarów. Używanie tabel tymczasowych (lub funkcji wycenianych w tabeli) ułatwiało w wielu przypadkach wiele aspektów przetwarzania. – overslacked

2

Podejście Tom H będzie działać. Można uprościć to tak, jeśli masz kolumnę tożsamości:

SELECT T1.id, T1.value_column1, avg(T2.value_column1) 
FROM table1 T1 
INNER JOIN table1 T2 ON T2.Id BETWEEN T1.Id-19 AND T1.Id 
+0

Nie wiem o MySQL, ale w MS SQL Server, który nie zadziała. Kolumny identyfikacji nie mogą być sekwencyjne ani ciągłe. –

+0

Będą, jeśli nie użyjesz SET IDENTITY_INSERT ON, lub usuniesz ceny? W takim przypadku można przenieść dane do tabeli tymczasowej z kolumną tożsamości uporządkowaną według daty. – Andomar

+0

Zgadzam się z Tomem. IDENTYFIKACJA (lub w języku MySQL, klucz podstawowy klucza auto_increment) może nie być sekwencyjna lub ciągła. Co się stanie, jeśli usuniesz niektóre wiersze ze środka stołu? Miałbyś przerwy w kluczu. –

0

Z mojego doświadczenia wynika, Mysql jak z 5.5.x nie ma tendencję do korzystania indeksów wybiera zależnych, czy podzapytania lub dołączyć. Może to mieć bardzo znaczący wpływ na wydajność, gdy zależne kryteria wyboru zmieniają się w każdym rzędzie.

Średnia ruchoma to przykład zapytania, które należy do tej kategorii. Czas wykonania może wzrosnąć wraz z kwadratem wierszy. Aby tego uniknąć, wybierz silnik bazy danych, który może wykonywać indeksowane wyszukiwania zależnych wyborów. Uważam, że postgres skutecznie działa na ten problem.

1

Moje rozwiązanie dodaje numer wiersza w tabeli. Poniższy przykładowy kod może pomóc:

set @MA_period=5; 
select id1,tmp1.date_time,tmp1.c,avg(tmp2.c) from 
(select @b:[email protected]+1 as id1,date_time,c from websource.EURUSD,(select @b:=0) bb order by date_time asc) tmp1, 
(select @a:[email protected]+1 as id2,date_time,c from websource.EURUSD,(select @a:=0) aa order by date_time asc) tmp2 
where id1>@MA_period and id1>=id2 and id2>([email protected]_period) 
group by id1 
order by id1 asc,id2 asc 
+0

w przypadku użycia warunku do wybrania określonych rekordów z tabeli (tutaj nazwanego websource.EURUSD) należy użyć dokładnie tego samego warunku w obu podselekcjach (aliasach tmp1 i tmp2) –

1

Zdaję sobie sprawę, że ta odpowiedź jest o około 7 lat za późno. Miałem podobny wymóg i sądziłem, że udostępnię moje rozwiązanie na wypadek, gdyby było przydatne dla kogoś innego.

Istnieje kilka rozszerzeń MySQL do analizy technicznej, które obejmują prostą średnią ruchomą. Są bardzo łatwe w instalacji i obsłudze: https://github.com/mysqludf/lib_mysqludf_ta#readme

Po zainstalowaniu UDF (zgodnie z instrukcjami w pliku README), można dołączyć prosty średniej kroczącej w select tak:

SELECT TA_SMA(value_column1, 20) AS sma_20 FROM table1 ORDER BY datetime_column1 
Powiązane problemy