MYSQL CTE 递归更新

标签 mysql recursion common-table-expression

我有一个 MYSQL 表,其中包含每隔 5 分钟显示开盘价、最高价、最低价、收盘价 (OHLC) 的股市数据。使用 OHLC,我有兴趣导出 4 列:Heikin Ashi Open、Heikin Ashi High、Heikin Ashi Low、Heikin Ashi Close。

4列的公式如下:

Heikin Ashi Close:  (Open+High+Low+Close)/4
Heikin Ashi Open:  [Heikin Ashi Open(Previous Row) + Heikin Ashi Close(Previous Row)]/2
Heikin Ashi High:  Max(High, Heikin Ashi Open, Heikin Ashi Close)
Heikin Ashi Low:  Min(High, Heikin Ashi Open, Heikin Ashi Close)

导出 Heikin Ashi Close 很简单。然而,平均足公开赛是从前一排的平均足公开赛和平均足收盘赛衍生而来的。第 2 行根据第 1 行 Heikin Ashi Open 和 Heikin Ashi Close 进行计算。第 3 行根据第 2 行 Heikin Ashi Open 和 Heikin Ashi Close 等进行计算...

我认为这可以使用 MYSQL 的 CTE 递归功能来完成,但我不确定如何实现它。

你能帮忙吗?

以下是示例数据的 CREATE 和 INSERT 语句:

CREATE TABLE `heikin_ashi_temp1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `timestamp` datetime DEFAULT NULL,
  `scrip_name` varchar(100) DEFAULT NULL,
  `open` float DEFAULT NULL,
  `high` float DEFAULT NULL,
  `low` float DEFAULT NULL,
  `close` float DEFAULT NULL,
  `ha_open` float DEFAULT NULL,
  `ha_high` float DEFAULT NULL,
  `ha_low` float DEFAULT NULL,
  `ha_close` float DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=256 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `market`.`heikin_ashi_temp1`
(`id`,
`timestamp`,
`scrip_name`,
`open`,
`high`,
`low`,
`close`,
`ha_open`,
`ha_high`,
`ha_low`,
`ha_close`)
VALUES
(1,'2020-01-17 09:19:59','ACC20JANFUT',1507.2,1507.2,1499.65,1502.5,NULL,NULL,NULL,NULL),
(2,'2020-01-17 09:20:35','ACC20JANFUT',1502.5,1515.2,1502.5,1503.45,NULL,NULL,NULL,NULL),
(3,'2020-01-17 09:26:35','ACC20JANFUT',1514.65,1517,1511.1,1511.55,NULL,NULL,NULL,NULL),
(4,'2020-01-17 09:32:33','ACC20JANFUT',1514.05,1514.05,1510.6,1512,NULL,NULL,NULL,NULL),
(5,'2020-01-17 09:35:34','ACC20JANFUT',1512.45,1516,1510,1511.7,NULL,NULL,NULL,NULL),
(6,'2020-01-17 09:41:35','ACC20JANFUT',1516,1516,1512.1,1513.95,NULL,NULL,NULL,NULL),
(7,'2020-01-17 09:47:34','ACC20JANFUT',1513.35,1513.35,1511.6,1512,NULL,NULL,NULL,NULL),
(8,'2020-01-17 09:50:31','ACC20JANFUT',1511.7,1513.4,1510.4,1511.3,NULL,NULL,NULL,NULL),
(9,'2020-01-17 09:56:34','ACC20JANFUT',1513.4,1516.7,1513.15,1513.95,NULL,NULL,NULL,NULL),
(10,'2020-01-17 10:02:34','ACC20JANFUT',1516.15,1519,1514.15,1514.65,NULL,NULL,NULL,NULL),
(11,'2020-01-17 09:19:59','ADANIENT20JANFUT',217,217.05,215.35,215.5,NULL,NULL,NULL,NULL),
(12,'2020-01-17 09:20:35','ADANIENT20JANFUT',215.45,216,214.15,215.65,NULL,NULL,NULL,NULL),
(13,'2020-01-17 09:26:34','ADANIENT20JANFUT',215.5,217,214.75,215.8,NULL,NULL,NULL,NULL),
(14,'2020-01-17 09:32:33','ADANIENT20JANFUT',216.5,216.9,216,216.2,NULL,NULL,NULL,NULL),
(15,'2020-01-17 09:35:34','ADANIENT20JANFUT',216.85,217.65,216.5,217.4,NULL,NULL,NULL,NULL),
(16,'2020-01-17 09:41:35','ADANIENT20JANFUT',216.6,217.45,216.25,216.65,NULL,NULL,NULL,NULL),
(17,'2020-01-17 09:47:34','ADANIENT20JANFUT',217.4,218.65,217.3,217.7,NULL,NULL,NULL,NULL),
(18,'2020-01-17 09:50:31','ADANIENT20JANFUT',217.95,218.05,217.5,218.05,NULL,NULL,NULL,NULL),
(19,'2020-01-17 09:56:33','ADANIENT20JANFUT',217.65,217.65,217.45,217.5,NULL,NULL,NULL,NULL),
(20,'2020-01-17 10:02:34','ADANIENT20JANFUT',217.85,218.2,217.5,217.6,NULL,NULL,NULL,NULL);


最佳答案

检查:

UPDATE heikin_ashi_temp t1
JOIN ( SELECT id,
              `timestamp`,
              open,
              high,
              low,
              close,
              CASE WHEN @open=0
                   THEN @open:=open
                   ELSE @open:=(@open+@close)/2
                   END AS ha_open,
              @close:=(Open+High+Low+Close)/4 AS ha_close
       FROM heikin_ashi_temp, (SELECT @close:=0, @open:=0) vars
       ORDER BY `timestamp` ) t2 USING (id)
SET t1.ha_open = t2.ha_open,
    t1.ha_close = t2.ha_close,
    t1.ha_high = GREATEST(t2.high, t2.ha_open, t2.ha_close),
    t1.ha_low = LEAST(t2.high, t2.ha_open, t2.ha_close);

fiddle

PS。注意 - 源数据已更改,最后 4 个字段值被清除,然后“从零”重新计算。

关于MYSQL CTE 递归更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59783328/

相关文章:

postgresql - 如何创建将父 ID 和祖 parent ID 插入数组的递归 CTE 查询

sql - 比多个 SELECT 语句更好的方法?

php - 如何从 PHP 代码中调用 MySQL 存储过程?

PHP 和 'variable' mySQL 查询

python - Pymysql 使用 %s (参数占位符)执行联合查询时

python - 如何知道可以为 Python 3 中的平台设置的最大递归深度?

r - 列出 k 个数字的所有排列,取自 0 :k,,总和为 k

php - 为什么 mySQL 在我的 LIKE 查询中返回 0 个结果?

javascript - 计算 ReactJS 中父评论的线程数

sqlite - 没有CTE的SQLite 3树形列表