计算temp低于0的连续天数

时间:2014-11-19 18:02:52

标签: mysql

我正在尝试计算我的数据库中温度低于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;

3 个答案:

答案 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获得最长时间的冻结时间(它会返回低于零的天数以及该时间段的最后一天)。