我正在尝试计算我的数据库中温度低于0的连续天数。我可以使用选择计数但不是连续天数得到总数低于0的天数。然后我希望能够显示第一天和最后一天以及计数。 该表每分钟更新一次。
假设我有一个最小的表,例如:
datetime temp
11/14/2014 7:21:31 -2.4
11/14/2014 7:22:31 -2.4
11/15/2014 5:03:31 2.4
11/15/2014 5:04:31 2.4
11/16/2014 5:10:31 -0.2
11/16/2014 5:11:31 -0.2
11/17/2014 5:13:31 -0.2
11/17/2014 5:14:31 -0.2
11/18/2014 5:15:31 2
11/18/2014 5:16:31 2
在示例中,连续天数为2,第一个日期为2014年11月16日,最后一个日期为2014年11月17日,总天数(我可以得到)将为3。
感谢您的光临。
编辑: 我想要连续最长的连胜纪录。至于我如何获得数据,这是一个简单的select语句: 选择datetime,temp来自mytable;
答案 0 :(得分:1)
考虑以下内容......
数据集......
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
( dt datetime NOT NULL PRIMARY KEY
, temp DECIMAL(5,2) NOT NULL);
INSERT INTO my_table VALUES
('2014-11-14 7:21:31', -2.4),
('2014-11-14 7:22:31', -2.4),
('2014-11-15 5:03:31', 2.4),
('2014-11-15 5:04:31', 2.4),
('2014-11-16 5:10:31', -0.2),
('2014-11-16 5:11:31', -0.2),
('2014-11-17 5:13:31', -0.2),
('2014-11-17 5:14:31', -0.2),
('2014-11-18 5:15:31', 2),
('2014-11-18 5:16:31', 2);
解决方案1 - 如果您只想知道最长跑的长度......
SELECT MAX(@count := IF(a.result = b.result, @count + 1, 1)) LongestRun
FROM
( SELECT DISTINCT DATE(x.dt) date
, COALESCE(y.temp,x.temp) < 0 result
FROM my_table x
LEFT
JOIN my_table y
ON DATE(y.dt) = DATE(x.dt) AND y.temp < 0
) a
CROSS
JOIN (SELECT @count := 0) vars
LEFT
JOIN
( SELECT DISTINCT DATE(x.dt) date
, COALESCE(y.temp,x.temp) < 0 result
FROM my_table x
LEFT
JOIN my_table y
ON DATE(y.dt) = DATE(x.dt) AND y.temp < 0
) b
ON b.date = a.date - INTERVAL 1 DAY
WHERE a.result = 1;
+------------+
| LongestRun |
+------------+
| 2 |
+------------+
解决方案2 - 如果您还想要其他一些信息
SELECT a.date start
, MIN(c.date) end
, DATEDIFF(MIN(c.date),a.date) + 1 LongestRun
FROM
( SELECT DISTINCT DATE(x.dt) date
, COALESCE(y.temp,x.temp) < 0 result
FROM my_table x
LEFT
JOIN my_table y
ON DATE(y.dt) = DATE(x.dt) AND y.temp < 0
) a
LEFT
JOIN
( SELECT DISTINCT DATE(x.dt) date
, COALESCE(y.temp,x.temp) < 0 result
FROM my_table x
LEFT
JOIN my_table y
ON DATE(y.dt) = DATE(x.dt) AND y.temp < 0
) b
ON b.date = a.date - INTERVAL 1 DAY
AND b.result = 1
LEFT
JOIN
( SELECT DISTINCT DATE(x.dt) date
, COALESCE(y.temp,x.temp) < 0 result
FROM my_table x
LEFT
JOIN my_table y
ON DATE(y.dt) = DATE(x.dt) AND y.temp < 0
) c
ON c.date >= a.date
AND c.result = 1
LEFT
JOIN
( SELECT DISTINCT DATE(x.dt) date
, COALESCE(y.temp,x.temp) < 0 result
FROM my_table x
LEFT
JOIN my_table y
ON DATE(y.dt) = DATE(x.dt) AND y.temp < 0
) d
ON d.date = c.date + INTERVAL 1 DAY
AND d.result = 1
WHERE a.result = 1
AND b.date IS NULL
AND c.date IS NOT NULL
AND d.date IS NULL
GROUP
BY a.date
ORDER
BY LongestRun DESC
LIMIT 1;
+------------+------------+------------+
| start | end | LongestRun |
+------------+------------+------------+
| 2014-11-16 | 2014-11-17 | 2 |
+------------+------------+------------+
对于汇总数据,只需发出单独的查询。
答案 1 :(得分:0)
您需要使用date
字段将表格与自己联系起来。像这样:
SELECT dt, temp FROM
(
SELECT date(t1.`datetime`) as dt, t1.temp
FROM mytable t1 LEFT JOIN mytable AS t2
ON date(t2.`datetime`) = (date(t1.`datetime`)-interval 1 day)
) TMP WHERE temp < 0
答案 2 :(得分:0)
使用自定义变量和一些增量逻辑来计算冻结天数(温度低于零)。这应该让你开始
SELECT
t1.endofstreakdate,
IF(t1.freeze > 0, @m := @m + 1, @m := t1.freeze) AS streak
FROM (
SELECT
DATE(t.datetime) AS endofstreakdate,
DAYOFYEAR(t.datetime) AS doy,
MIN(t.temp) AS low,
IF(MIN(t.temp) < 0, @i := @i + 1, @i := @i - @i) AS freeze
FROM (
SELECT
@i := 0,
@m := 0
) v,
temperature t
GROUP BY doy
) t1
LEFT JOIN (
SELECT
DAYOFYEAR(t.datetime) AS doy,
MIN(t.temp) AS low,
IF(MIN(t.temp) < 0, @i := @i + 1, @i := @i - @i) AS freeze
FROM (
SELECT
@i := 0,
@m := 0
) v,
temperature t
GROUP BY doy
) t2
ON t2.doy = t1.doy - 1
这将为您提供所有唯一日期(没有时间)的列表以及温度低于0的天数,例如
endofstreakdate streak
2014-11-14 1
2014-11-15 0
2014-11-16 1
2014-11-17 2
2014-11-18 0
您现在可以ORDER BY streak DESC, endofstreakdate ASC LIMIT 1
获得最长时间的冻结时间(它会返回低于零的天数以及该时间段的最后一天)。