注意: 我的问题数据在SQLFiddle就在这里 可以查询它。
我有来自表的数据并使用以下逻辑放入临时表,但BETWEEN
开始和结束日期时间戳是根据存储过程中的其他逻辑动态生成的。
SET @RowNum = 0;
DROP TEMPORARY TABLE IF EXISTS temp;
CREATE TEMPORARY TABLE temp AS
SELECT @RowNum := @RowNum + 1 RowNum
, TimeStr
, Value
FROM mytable
WHERE TimeStr BETWEEN '2018-01-31 06:15:56' AND '2018-01-31 19:27:09'
AND iQuality = 3 ORDER BY TimeStr;
这给了一个临时表,其行号从最早的基于TimeStr
记录开始按顺序递增一个数字,因此最旧的是第一个记录的时间或RowNum
1。
临时表
您可以访问此临时表数据并在我创建的SQLFiddle上查看此处的查询,但我在那里尝试了一些事情,您会看到哪些内容不在&#39我给了我所需要的东西。
我需要根据每个集合中的TimeStr
值设置每个 ON 和 OFF 的时间,我可以使用{{{ 3}}功能。
我很难弄清楚如何让它给我每个 ON 和 OFF 记录的结果。记录始终按从最旧到最新的顺序排列,行号也始终从1开始。
我有些需要给出每两个记录,其中一个接着RowNum
值明智地匹配CycleNum
从1开始,每个 ON 增加一个关闭循环或设置。
我可以使用TIMEDIFF(MAX(TimeStr), MIN(TimeStr)) as duration
,但我不确定如何最好地按顺序对每两个RowNum
记录进行分组,如下所述,为每组提供后续CycleNum
值增量。
预期输出显示所有 ON 和 OFF 周期的下方屏幕截图或组和序列中的每两个RowNum
。
我需要输出包括每个 ON 和 OFF 周期的开始时间,结束时间以及开始和停止之间的持续时间。
答案 0 :(得分:3)
如果你能保证两件事:
然后你可以用一个相对简单的join
来做到这一点。代码如下:
SELECT (@rn := @rn + 1) as cycle, t.*, tnext.timestr,
timediff(tnext.timestr, t.timestr)
FROM temp t JOIN
temp tnext
ON t.rownum = tnext.rownum - 1 and
t.value = 1 and
tnext.value = 0 cross join
(SELECT @rn := 0) params;
如果这些条件不成立,则需要更复杂的逻辑。
答案 1 :(得分:1)
快速而肮脏的方法就是:
SELECT
T1.TimeStr AS StartTime,
(SELECT T2.TimeStr FROM temp AS T2 WHERE T2.RowNum = T1.RowNum+1) AS StopTime,
TIMEDIFF((SELECT T2.TimeStr FROM temp AS T2 WHERE T2.RowNum = T1.RowNum+1),
T1.TimeStr) AS Duration
FROM temp AS T1
WHERE Value = 1;
似乎必须有更好的方法来做到这一点。两个子查询会很慢。
你可以分两步完成:
CREATE TEMPORARY TABLE startstop AS
SELECT
T1.TimeStr AS StartTime,
(SELECT T2.TimeStr FROM temp AS T2 WHERE T2.RowNum = T1.RowNum+1) AS StopTime,
0 AS Duration
FROM temp AS T1
WHERE Value = 1;
UPDATE startstop SET Duration = StopTime - StartTime;
但是我不能在小提琴中测试这个。
答案 2 :(得分:1)
这是一个更简单的方法:
SELECT
t1.TimeStr AS StartTime,
t2.TimeStr AS EndTime,
TIMEDIFF(t2.TimeStr, t1.TimeStr) AS Duration
FROM temp t1
INNER JOIN temp t2 ON t2.RowNum = t1.RowNum + 1
WHERE
t2.Value = 0
AND t1.Value = 1