SQL:查找带有备用0和1的行数。基本上需要找到此类序列的最大数量

时间:2019-11-25 20:15:05

标签: mysql sql data-analysis

这与此处提出的另一个问题有关 SQL: count all records with consecutive occurrence of same value for each device set and return the highest count

但略有不同。让我用一张桌子解释一下。在下表中,我们需要获得遵循模式1 0的所有条目的最大计数,该模式首先打开,然后再次打开和关闭,等等。基本上,需要检索连续打开和关闭的任何device(device_id)最大计数为101010(算作3)模式。 关于链接将检索相同但具有相同连续值的链接。需要调整为具有1 0模式

Device ID        on_off             DateTime
--------------------------------------------------
07777778999       1               18-12-2016 17:15
07777778123       1               18-12-2016 18:10
07777778999       1               19-12-2016 19:30
07777778999       1               19-12-2016 20:15
07777778999       0               19-12-2016 21:15
07777778999       1               20-12-2016 11:15
07777778999       0               20-12-2016 12:15
07777778999       1               20-12-2016 17:15
07777778999       0               20-12-2016 17:25
07777778999       1               20-12-2016 17:35
07777778999       0                20-12-2016 17:45
07777778999       0               20-12-2016 17:55
07777778999       0               20-12-2016 18:50
07777778999       0               20-12-2016 18:55
07777778999       1                20-12-2016 19:05
07777778999       0               20-12-2016 19:25
07777778999       1               20-12-2016 19:30
07777778999       0               20-12-2016 19:45
07777778123       1               28-12-2016 20:10
07777778123       1               28-12-2016 20:15
07777778123       1               28-12-2016 20:25
07777778123       1               28-12-2016 20:30
07777778123       0               28-12-2016 20:40

---------------------------------------------------------------- ```
so my expected table would be


```Device ID        max_cons_on_off       
-------------------------------
07777778999       4               
07777778123       1    ```           



1 个答案:

答案 0 :(得分:0)

这似乎更复杂。我的想法是通过查看前两行来了解岛屿的起点。

select t.*,
       sum( case when oo_prev = 0 and oo_prev2 = 1 then 0 else 1 end) Over (partition by device_id order by datetime) as grp
from (select t.*,
             lag(on_off) over (partition by device_id order by datetime) as oo_prev,
             lag(on_off, 2) over (partition by device_id order by datetime) as oo_prev2
      from t
     ) t;

然后聚合,过滤并再次聚合:

select device_id, max(cnt)
from (select device_id, count(*) as cnt
      from (select t.*,
                   sum( case when oo_prev = 0 and oo_prev2 = 1 and on_off = 1 and oo_next = 0 then 0 else 1 end) Over (partition by device_id order by datetime) as grp
            from (select t.*,
                         lag(on_off) over (partition by device_id order by datetime) as oo_prev,
                         lag(on_off, 2) over (partition by device_id order by datetime) as oo_prev2
                         lead(on_off, 1) over (partition by device_id order by datetime) as oo_next
                  from t
                 ) t
            ) t
     where on_off = 1 and oo_next = 0
     group by device_id, grp
    ) t
group by device_id;