Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie kann ich mit MySQL die höchsten % täglichen Preisänderungen berechnen?

Ein Problem, das ich auf Anhieb sehe, ist die Verwendung eines Zeitstempel-Datentyps für das Datum. Dies wird Ihre SQL-Abfrage aus zwei Gründen verkomplizieren - Sie müssen einen Bereich verwenden oder in Ihrer Where-Klausel in ein tatsächliches Datum konvertieren, aber noch wichtiger , da Sie angeben, dass Sie am heutigen Schlusskurs und am gestrigen Schlusskurs interessiert sind, müssen Sie die Tage im Auge behalten, an denen der Markt geöffnet ist - also ist die Montagsabfrage anders als di - fri und jeder Tag, an dem der Markt geschlossen ist ein Feiertag muss ebenfalls berücksichtigt werden.

Ich würde eine Spalte wie mktDay hinzufügen und sie jeden Tag erhöhen, an dem der Markt für Geschäfte geöffnet ist. Ein anderer Ansatz könnte darin bestehen, eine Spalte „vorherClose“ einzufügen, wodurch Ihre Berechnung trivial wird. Mir ist klar, dass dies gegen die Normalform verstößt, aber es erspart einen teuren Self-Join in Ihrer Abfrage.

Wenn Sie die Struktur nicht ändern können, führen Sie einen Self-Join durch, um den Schlusskurs von gestern zu erhalten, und Sie können die prozentuale Änderung berechnen und nach dieser prozentualen Änderung sortieren, wenn Sie dies wünschen.

Unten ist Erics Code, etwas aufgeräumt, der auf meinem Server ausgeführt wurde, auf dem mysql 5.0.27 läuft

select
   p_today.`ticker`,
   p_today.`date`,
   p_yest.price as `open`,
   p_today.price as `close`,
   ((p_today.price - p_yest.price)/p_yest.price) as `change`
from
   prices p_today
   inner join prices p_yest on
       p_today.ticker = p_yest.ticker
       and date(p_today.`date`) = date(p_yest.`date`) + INTERVAL 1 DAY
       and p_today.price > 0
       and p_yest.price > 0
       and date(p_today.`date`) = CURRENT_DATE
order by `change` desc
limit 10

Beachten Sie die Backticks, da einige Ihrer Spaltennamen und Erics Aliase reservierte Wörter waren.

Beachten Sie auch, dass die Verwendung einer where-Klausel für die erste Tabelle eine kostengünstigere Abfrage wäre - die where get wird zuerst ausgeführt und muss nur versuchen, sich selbst bei den Zeilen zu verbinden, die größer als null sind und das heutige Datum haben

select
   p_today.`ticker`,
   p_today.`date`,
   p_yest.price as `open`,
   p_today.price as `close`,
   ((p_today.price - p_yest.price)/p_yest.price) as `change`
from
   prices p_today
   inner join prices p_yest on
       p_today.ticker = p_yest.ticker
       and date(p_today.`date`) = date(p_yest.`date`) + INTERVAL 1 DAY

       and p_yest.price > 0
where p_today.price > 0
    and date(p_today.`date`) = CURRENT_DATE
order by `change` desc
limit 10