数据点的单表时间序列(例如,功率或温度读数)。 如何使用MySQL 5.x有效地选择一个样本来生成包括所有局部最小值,最大值和其他数据的第n个采样的图形?
其他SQL解决方案使用:
自我联接,使用id-1和id + 1上的联接,选择其中prev.val
使用LEAD和LAG函数选择上一条和下一条记录的类似逻辑
在ID上进行模数运算以选择样本,除非偶然选择,否则将错过最大值/最小值
MySQL 5.x-临时表上没有自我连接,没有LEAD和LAG函数,并且此数据没有顺序ID-因此需要使用临时表来顺序地重新分配ID。
样本数据:
id datetime val
194038 2018-07-01 11:30:20 102
194050 2018-07-01 11:31:40 86
194054 2018-07-01 11:31:50 101
194065 2018-07-01 11:33:51 98
194075 2018-07-01 11:35:50 97
194085 2018-07-01 11:37:50 99
194095 2018-07-01 11:39:50 114
194100 2018-07-01 11:40:40 158
194105 2018-07-01 11:40:50 116
194115 2018-07-01 11:41:00 139
194124 2018-07-01 11:41:30 110
194128 2018-07-01 11:41:40 121
194132 2018-07-01 11:41:50 168
194143 2018-07-01 11:43:51 135
194153 2018-07-01 11:45:50 128
194163 2018-07-01 11:47:00 95
194173 2018-07-01 11:49:00 69
194186 2018-07-01 11:51:00 64
194194 2018-07-01 11:51:31 16
194198 2018-07-01 11:51:41 45
194209 2018-07-01 11:53:40 60
194219 2018-07-01 11:55:40 59
194229 2018-07-01 11:57:40 68
194246 2018-07-01 11:59:40 67
使用临时表的解决方案有效,但效率极低:(请参阅内联注释)
DROP TEMPORARY TABLE IF EXISTS tmp;
DROP TEMPORARY TABLE IF EXISTS tmp2;
DROP TEMPORARY TABLE IF EXISTS tmp3;
DROP TEMPORARY TABLE IF EXISTS tmp4;
# Get data of interest into tmp with sequential ID
CREATE TEMPORARY TABLE tmp (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY)
SELECT datetime, val
FROM log
ORDER BY datetime;
# Make copies of tmp (MySql can't self join on temporary tables)
CREATE TEMPORARY TABLE tmp2
SELECT * FROM tmp;
CREATE TEMPORARY TABLE tmp3
SELECT * FROM tmp;
SELECT A.datetime, A.val
FROM tmp A, tmp2 P, tmp3 N
# Join next and previous records (emulates LAG() and LEAD())
WHERE A.id = P.id + 1
AND A.id = N.id - 1
AND (
(
# select local maxima
A.val >= P.val
AND A.val >= N.val
)
OR (
# select local minima
A.val <= P.val
AND A.val <= N.val
)
# select a sampling of other records
# mod value changed by calling code depending on zoom level of graph
OR A.id mod 4 = 0
)
ORDER BY A.datetime
预期和实际结果:
datetime val
2018-07-01 11:31:40 86
2018-07-01 11:31:50 101
2018-07-01 11:33:51 98
2018-07-01 11:35:50 97
2018-07-01 11:40:40 158
2018-07-01 11:40:50 116
2018-07-01 11:41:00 139
2018-07-01 11:41:30 110
2018-07-01 11:41:40 121
2018-07-01 11:41:50 168
2018-07-01 11:47:00 95
2018-07-01 11:51:31 16
2018-07-01 11:51:41 45
2018-07-01 11:53:40 60
2018-07-01 11:55:40 59
2018-07-01 11:57:40 68
是否有更好的方法(或优化此方法)?