如何使用MySQL计算每日最高价格变化百分比?

All*_*Liu 8 mysql sql

我有一张表prices,其中包括我每天跟踪的股票收盘价.

这是架构:

CREATE TABLE `prices` (
  `id` int(21) NOT NULL auto_increment,
  `ticker` varchar(21) NOT NULL,
  `price` decimal(7,2) NOT NULL,
  `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`),
  KEY `ticker` (`ticker`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2200 ;
Run Code Online (Sandbox Code Playgroud)

我试图计算今天和昨天价格值大于0的任何东西的价格下降百分比.随着时间的推移,这张桌子将是巨大的,我担心性能.我认为这必须在MySQL方面而不是PHP方面完成,因为LIMIT这里需要它.

我如何处理最后2个日期并在MySQL中进行%drop计算?

任何建议将不胜感激.

Sco*_*ott 5

我立即看到的一个问题是对日期使用时间戳数据类型,这将使​​您的 sql 查询复杂化,原因有两个 - 您必须在 where 子句中使用范围或转换为实际日期,但是,更重要的是,由于您声明您对今天的收盘价和昨天的收盘价感兴趣,因此您必须跟踪市场开放的日期 - 因此周一的查询与周二至周五不同,并且任何一天市场休市假期也必须考虑在内。

我会添加一个像 mktDay 这样的列,并在市场开放的每一天增加它。另一种方法可能是包含一个“previousClose”列,这使得您的计算变得简单。我意识到这违反了正常形式,但它节省了查询中昂贵的自连接。

如果您无法更改结构,那么您将进行自连接以获得昨天的收盘价,如果您愿意,您可以计算百分比变化并按该百分比变化进行排序。

下面是 Eric 的代码,经过一些清理,它在我运行 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
Run Code Online (Sandbox Code Playgroud)

请注意反引号,因为某些列名称和 Eric 的别名是保留字。

另请注意,对第一个表使用 where 子句将是一个更便宜的查询 - 首先执行 where get,并且只需尝试对大于零且具有今天日期的行进行自联接

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
Run Code Online (Sandbox Code Playgroud)