首页 > 解决方案 > 如何计算来自不同行的数据

问题描述

我有下表来监控每天的价格,我想在两天之间进行计算,比如今天的收盘价 - 前一天的开盘价,例如周四收盘 - 周三开盘,所以我可以看到差异。

此外,周末没有记录,所以我如何进行 2 种不同的计算,例如 1. 周一的收盘价 - 周日返回相同的周一价格,2. 周一的收盘价 - 上周五的开盘价等

INSERT INTO goods(date,day,open,high,low,close,`range(daily high- low)`) VALUES
 ('2018-11-01','Thu',1.08430,1.08766,1.08175,1.08285,0.00591),
 ('2018-11-02','Fri',1.08319,1.08585,1.07988,1.07988,0.00597),
 ('2018-11-05','Mon',1.08258,1.08389,1.08011,1.08155,0.00378),
 ('2018-11-06','Tue',1.08160,1.08489,1.07461,1.07469,0.01028),
 ('2018-11-07','Wed',1.07543,1.07646,1.07094,1.07150,0.00552),
 ('2018-11-08','Thu',1.07148,1.07571,1.07083,1.07393,0.00488),
 ('2018-11-09','Fri',1.07409,1.07651,1.07124,1.07125,0.00527),
 ('2018-11-12','Mon',1.07190,1.07389,1.06759,1.06878,0.00630),
 ('2018-11-13','Tue',1.06830,1.06977,1.06609,1.06658,0.00368)

理想输出1:

  date,         day, open,    high,   low,close, diff
 ('2018-11-01','Thu',1.08430,1.08766,1.08175,1.08285, ..
 ('2018-11-02','Fri',1.08319,1.08585,1.07988,1.07988, - 0.00442
 ('2018-11-05','Mon',1.08258,1.08389,1.08011,1.08155,- 0.00164
 ('2018-11-06','Tue',1.08160,1.08489,1.07461,1.07469,-0.00789

输出 2:

  date,         day, open,    high,   low,close, diff
 ('2018-11-01','Thu',1.08430,1.08766,1.08175,1.08285, ..
 ('2018-11-02','Fri',1.08319,1.08585,1.07988,1.07988, - 0.00442
 ('2018-11-05','Mon',1.08258,1.08389,1.08011,1.08155, 1.08155
 ('2018-11-06','Tue',1.08160,1.08489,1.07461,1.07469,-0.00789

我用的是php7.1,mysql

标签: mysqlsqldatabase

解决方案


如果您使用的是 MySQL 8.0,则可以使用LAG()访问按日期排序的前一条记录。这将愉快地忽略几天内的差距,因此将周一收盘价与周五开盘价进行比较:

SELECT
    g.*,
    g.close - LAG(g.open) OVER(ORDER BY g.date) price_diff
FROM goods g

DB Fiddle 上的演示


在旧版本的 MySQL 中,通常会使用自连接和关联子查询以及NOT EXISTS条件来检索先前的记录:

SELECT g.*, g.close - g1.open price_diff
FROM goods g
LEFT JOIN goods g1 
    ON g1.date < g.date
    AND NOT EXISTS (
        SELECT 1 FROM goods g2 WHERE g2.date < g.date AND g2.date > g1.date
    )

g是当前记录(比如:今天)。g1代表昨天的记录:为了识别它,我们指示 RDBMS:

  • g1的日期低于g的日期
  • g2存在日期低于今天 ( g) 且高于昨天 ( ) 的记录 ( g1)

这两个条件的组合允许 RDMS 唯一标识相关记录(昨天的),然后可以在计算中使用其值。

DB Fiddle 上的演示


推荐阅读