按月、日、小时+间隙和孤岛问题分组

Posted

技术标签:

【中文标题】按月、日、小时+间隙和孤岛问题分组【英文标题】:Group by month, day, hour + gaps and islands problem 【发布时间】:2018-11-13 16:38:01 【问题描述】:

我需要计算(以百分比表示)状态在一天、几小时或一个月(工作时间)中持续多长时间。

我将我的表格简化为这个:

| date                      | status    |
|-------------------------- |--------   |
| 2018-11-05T19:04:21.125Z  | true      |
| 2018-11-05T19:04:22.125Z  | true      |
| 2018-11-05T19:04:23.125Z  | true      |
| 2018-11-05T19:04:24.125Z  | false     |
| 2018-11-05T19:04:25.125Z  | true      |
....

我需要得到这个结果(取决于参数):

几个小时:

| date                      | working_time |
|-------------------------- |--------------|
| 2018-11-05T00:00:00.000Z  | 14           |
| 2018-11-05T01:00:00.000Z  | 15           |
| 2018-11-05T02:00:00.000Z  | 32           |
|...                        | ...          |
| 2018-11-05T23:00:00.000Z  | 13           |

几个月:

| date                      | working_time |
|-------------------------- |--------------|
| 2018-01-01T00:00:00.000Z  | 14           |
| 2018-02-01T00:00:00.000Z  | 15           |
| 2018-03-01T00:00:00.000Z  | 32           |
|...                        | ...          |
| 2018-12-01T00:00:00.000Z  | 13           |

我的 SQL 查询如下所示:

 SELECT date_trunc('month', date)                                         as date,
       round((EXTRACT(epoch from sum(time_diff)) / 25920) :: numeric, 2) as working_time
FROM (SELECT date,
             status as current_status,
             (lag(status, 1) OVER (ORDER BY date)) AS previous_status,
             (date -(lag(date, 1) OVER (ORDER BY date))) AS time_diff
      FROM table
     ) as raw_data
WHERE current_status = TRUE AND previous_status = TRUE
GROUP BY date_trunc('month', date)
ORDER BY date;

它工作正常,但速度很慢。关于优化的任何想法?也许使用 Row_Number() 函数?

【问题讨论】:

是否需要将连续的TRUE 或设计周期内的任何行计算为TRUE 我需要连续数 TRUE。让我写一个小例子: 【参考方案1】:

试试这个:

   SELECT t.month_reference as date,
            round(  sum(if(t_aux.status,1,0))  / 25920) :: numeric, 2) as working_time 

#我假设你使用这个数字是因为系统的正常运行时间是60*18*24,

#如果我想要当月的总秒数 60*60*24*day(Last_day(t.month_reference)),我会使用它

FROM (SELECT date_trunc('month', t.date) as month_reference
          FROM table
         ) as t
    left join table t_aux
    on t.month_reference=date_trunc('month', t_aux.date) 

所以当我们按月份分组时,sum() 只会找到为真且具有引用月份的行

   and t_aux.date < 
    (select t1.date 
    from table t1 
    where t.month_reference=date_trunc('month', t1.date) 
    and t1.status=false 
    order by t1.date asc limit 1 )

我添加了这个,所以它只选择为 true 的行,直到它在同一月份参考中找到状态为 false 的行

    GROUP BY t.month_reference
    ORDER BY t.month_reference;

【讨论】:

以上是关于按月、日、小时+间隙和孤岛问题分组的主要内容,如果未能解决你的问题,请参考以下文章

Pandas 数据透视表和分组按月和小时

SQL按月统计,按日分组

Mysql按周,按月,按日,按小时分组统计数据

MySql按周,按月,按日分组统计数据

MySql按周,按月,按日分组统计数据

MySql按周,按月,按日分组统计数据