Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment puis-je calculer les meilleurs % de changements de prix quotidiens à l'aide de MySQL ?

Un problème que je vois dès le départ est l'utilisation d'un type de données d'horodatage pour la date, cela compliquera votre requête sql pour deux raisons - vous devrez utiliser une plage ou convertir en une date réelle dans votre clause where, mais, plus important encore , puisque vous déclarez que vous êtes intéressé par le cours de clôture d'aujourd'hui et le cours de clôture d'hier, vous devrez garder une trace des jours où le marché est ouvert - donc la requête du lundi est différente de celle du mardi au vendredi, et tous les jours où le marché est fermé pour un jour férié devra également être pris en compte.

J'ajouterais une colonne comme mktDay et l'incrémenterais chaque jour où le marché est ouvert aux affaires. Une autre approche pourrait être d'inclure une colonne 'previousClose' qui rend votre calcul trivial. Je me rends compte que cela viole la forme normale, mais cela évite une auto-jointure coûteuse dans votre requête.

Si vous ne pouvez pas modifier la structure, vous effectuerez une auto-jointure pour obtenir la clôture d'hier et vous pourrez calculer le % de changement et ordonner par ce % de changement si vous le souhaitez.

Ci-dessous se trouve le code d'Eric, nettoyé un peu, il a été exécuté sur mon serveur exécutant mysql 5.0.27

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

Notez les back-ticks car certains de vos noms de colonne et les alias d'Eric étaient des mots réservés.

Notez également que l'utilisation d'une clause where pour la première table serait une requête moins coûteuse - le where get est exécuté en premier et n'a qu'à tenter de s'auto-joindre sur les lignes supérieures à zéro et ayant la date du jour

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