【问题标题】:Still show the proper set of time even if there's no entry for that time即使该时间没有条目,仍然显示正确的时间集
【发布时间】:2014-05-08 17:13:49
【问题描述】:

我有这个查询,它从上午 12 点到晚上 11:45 获取平均值并将值按 15 分钟分组。

SELECT FROM_UNIXTIME(t_stamp/1000, '%m/%d/%Y %l:%i %p') as t_stamp,
    ROUND(AVG(CASE WHEN id = '001' THEN value END),2) Value1,   
    ROUND(AVG(CASE WHEN id = '002' THEN value END),2) Value2,
    ROUND(AVG(CASE WHEN id = '003' THEN value END),2) Value3

FROM table1
WHERE tagid IN ("001", "002", "003") and

date(from_unixtime(t_stamp/1000)) BETWEEN "2014-05-01" AND "2014-05-01"

GROUP BY DATE(from_unixtime(t_stamp/1000)), HOUR(from_unixtime(t_stamp/1000)), MINUTE(from_unixtime(t_stamp/1000))  DIV 15

输出如下所示

    t_stamp             |   Value1  |   Value2  |   Value3
05/01/2014 12:00 AM     |   199     |   99      |   100
05/01/2014 12:15 AM     |   299     |   19      |   140
05/01/2014 12:30 AM     |   399     |   59      |   106
05/01/2014 12:45 AM     |   499     |   59      |   112
.
.
.
05/01/2014 11:00 PM     |   149     |   199     |   100
05/01/2014 11:15 PM     |   599     |   93      |   123
05/01/2014 11:30 PM     |   129     |   56      |   150
05/01/2014 11:45 PM     |   109     |   60      |   134

它工作正常,但我注意到有时如果像 12:30 这样的时间没有条目而不是显示

    t_stamp             |   Value1  |   Value2  |   Value3
05/01/2014 12:00 AM     |   199     |   99      |   100
05/01/2014 12:15 AM     |   299     |   19      |   140
05/01/2014 12:30 AM     |   Null    |   Null    |   Null
05/01/2014 12:45 AM     |   499     |   59      |   112

它会像这样显示一组时间:

    t_stamp             |   Value1  |   Value2  |   Value3
05/01/2014 12:00 AM     |   199     |   99      |   100
05/01/2014 12:15 AM     |   299     |   19      |   140
05/01/2014 12:33 AM     |   122     |   141     |   234
05/01/2014 12:45 AM     |   499     |   59      |   112

我希望发生的是,当 15 分钟组没有时间时,它仍会显示正确的时间集,然后仅在列值上显示 null。我想要的输出是这样的:

    t_stamp             |   Value1  |   Value2  |   Value3
05/01/2014 12:00 AM     |   199     |   99      |   100
05/01/2014 12:15 AM     |   299     |   19      |   140
05/01/2014 12:30 AM     |   Null    |   Null    |   Null
05/01/2014 12:45 AM     |   499     |   59      |   112

我该怎么做?

谢谢。

【问题讨论】:

    标签: mysql time time-series missing-data


    【解决方案1】:

    您需要一个作为基数来源的表格作为开始。目前让我们假设它存在,它被称为cardinal

    然后,您需要创建一个查询(一个虚拟表),它将每十五分钟返回一次带有时间戳的行,从最早的相关时间戳开始,到最新的结束。以下是如何为您的查询执行此操作。

    SELECT '2014-05-01' + INTERVAL (cardinal.n * 15) MINUTE as t_stamp
      FROM cardinal
     WHERE cardinal.n <= 24*4
    

    然后你需要将该虚拟表加入到你现有的查询中,如下所示

    SELECT DATE_FORMAT(t_stamp.t_stamp, '%m/%d/%Y %l:%i %p') t_stamp,
           ROUND(AVG(CASE WHEN id = '001' THEN value END),2) Value1,   
           ROUND(AVG(CASE WHEN id = '002' THEN value END),2) Value2,
           ROUND(AVG(CASE WHEN id = '003' THEN value END),2) Value3
      FROM table1 AS t
      LEFT JOIN (
            SELECT '2014-05-01' + INTERVAL (cardinal.n * 15) MINUTE as t_stamp
              FROM cardinal
             WHERE cardinal.n <= 24*4
           ) AS t_stamp 
             ON t_stamp.t_stamp = FROM_UNIXTIME(t.t_stamp/1000)   
     WHERE tagid IN ("001", "002", "003")
       AND date(from_unixtime(t_stamp/1000)) BETWEEN "2014-05-01" AND "2014-05-01"
     GROUP BY DATE(from_unixtime(t_stamp/1000)), 
              HOUR(from_unixtime(t_stamp/1000)), 
              MINUTE(from_unixtime(t_stamp/1000))  DIV 15
    

    请注意,LEFT JOIN 可确保原始查询中的 NULL 值包含在结果集中。

    现在,这个神奇的cardinal 表从何而来?

    您可以将其生成为两个视图,如下所示。这个特殊的视图生成从 0 到 100 000 的数字,这对于一年的四分之一小时来说已经绰绰有余了。

    CREATE OR REPLACE VIEW cardinal10 AS
        SELECT 0 AS N UNION
        SELECT 1 AS N UNION
        SELECT 2 AS N UNION
        SELECT 3 AS N UNION
        SELECT 4 AS N UNION
        SELECT 5 AS N UNION
        SELECT 6 AS N UNION
        SELECT 7 AS N UNION
        SELECT 8 AS N UNION
        SELECT 9 AS N;
    
    
    CREATE OR REPLACE VIEW cardinal AS
        SELECT A.N + 10*(B.N + 10*(C.N + 10*(D.N + 10*(E.N)))) AS N
        FROM cardinal10 A,cardinal10 B,cardinal10 C, 
             cardinal10 D,cardinal10 E; 
    

    这是有关该主题的文章。 http://www.plumislandmedia.net/mysql/filling-missing-data-sequences-cardinal-integers/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-07
      • 2018-02-05
      • 1970-01-01
      • 2013-04-08
      • 2021-03-31
      • 2015-06-14
      • 1970-01-01
      相关资源
      最近更新 更多