Нахождение максимального размера острова SQL - PullRequest
0 голосов
/ 29 августа 2018

Текущий код sql суммирует все максимальные размеры островов в один. Я пытаюсь найти только максимальный размер острова для подряд часов Игнорирование минут и секунд в пределах даты и времени.

 select deviceid, grp -- min(readdate) as mn, max(readdate) as mx
       from (  select deviceid, readdate, sum(case when prev_rd >= readdate - interval '1 hour' then 1 else 0 end) over (partition by deviceid order by readdate rows between unbounded preceding and current row) as grp
               from (
                    select deviceid, readdate, lag(readdate) over (partition by deviceid order by readdate) as prev_rd
                    from metersWithExcess
                    order by readdate)
            ) tt
            group by deviceid, readdate, grp
           -- having mx > mn + 1 * interval '1 hour'

Есть ли способ вернуть обратно deviceid с его максимальным размером? Я пытаюсь найти самые длинные непрерывные почасовые показания

данные выглядят так:

    deviceid    readdate
91428   2018-08-27 18:04:42
91428   2018-08-27 17:04:42
91428   2018-08-27 16:04:42
91428   2018-08-27 12:04:42
91428   2018-08-27 11:04:42
91428   2018-08-26 20:04:42
91428   2018-08-26 17:04:40
91428   2018-08-26 16:04:40
91428   2018-08-26 15:04:40
91428   2018-08-26 12:04:40
91489   2018-08-26 06:00:49
91493   2018-08-27 06:58:44
91511   2018-08-27 12:57:01
91511   2018-08-27 10:57:01
91511   2018-08-27 09:57:01
91511   2018-08-26 23:57:01
91511   2018-08-26 22:57:01
91511   2018-08-26 20:57:01
91511   2018-08-26 13:56:59
91511   2018-08-26 12:56:59
91511   2018-08-26 10:56:59
91547   2018-08-26 16:59:07
91547   2018-08-26 15:59:07
91547   2018-08-26 14:59:07
91547   2018-08-26 11:59:07
91547   2018-08-26 04:59:07
91582   2018-08-27 12:01:45
91582   2018-08-26 19:01:45

в этом примере: максимальный размер 91428 будет равен 3, поскольку наибольшим размером для идентификатора 91428 является 18:04:42 / 17:04:42 / 16: 04: 42

1 Ответ

0 голосов
/ 30 августа 2018

То, как вы задаете вопрос, немного сбивает с толку, терминология «остров» и «максимальный размер» должна быть специфичной для вашей отрасли, но поможет ли такой подход «грубой силы»? Формат здесь:

deviceid, первое чтение, пробел до следующего чтения, второе чтение, пробел до следующего и т. Д.

Я прокомментировал свои критерии "ГДЕ разрыв1 = '01: 00: 00 'И ГЭП2 = '01: 00: 00'", но это нашло бы ваши последовательные почасовые показания.

WITH DEVICEID_TEST_DATA   AS


(     SELECT  CAST(91428  AS  bigint) AS deviceid   ,  CAST('2018-08-27 18:04:42' AS TIMESTAMP)  AS readdate UNION
      SELECT  91428     ,   '2018-08-27 17:04:42'         UNION
      SELECT  91428     ,   '2018-08-27 16:04:42'         UNION
      SELECT  91428     ,   '2018-08-27 12:04:42'         UNION
      SELECT  91428     ,   '2018-08-27 11:04:42'         UNION
      SELECT  91428     ,   '2018-08-26 20:04:42'         UNION
      SELECT  91428     ,   '2018-08-26 17:04:40'         UNION
      SELECT  91428     ,   '2018-08-26 16:04:40'         UNION
      SELECT  91428     ,   '2018-08-26 15:04:40'         UNION
      SELECT  91428     ,   '2018-08-26 12:04:40'         UNION
      SELECT  91489     ,   '2018-08-26 06:00:49'         UNION
      SELECT  91493     ,   '2018-08-27 06:58:44'         UNION
      SELECT  91511     ,   '2018-08-27 12:57:01'         UNION
      SELECT  91511     ,   '2018-08-27 10:57:01'         UNION
      SELECT  91511     ,   '2018-08-27 09:57:01'         UNION
      SELECT  91511     ,   '2018-08-26 23:57:01'         UNION
      SELECT  91511     ,   '2018-08-26 22:57:01'         UNION
      SELECT  91511     ,   '2018-08-26 20:57:01'         UNION
      SELECT  91511     ,   '2018-08-26 13:56:59'         UNION
      SELECT  91511     ,   '2018-08-26 12:56:59'         UNION
      SELECT  91511     ,   '2018-08-26 10:56:59'         UNION
      SELECT  91547     ,   '2018-08-26 16:59:07'         UNION
      SELECT  91547     ,   '2018-08-26 15:59:07'         UNION
      SELECT  91547     ,   '2018-08-26 14:59:07'         UNION
      SELECT  91547     ,   '2018-08-26 11:59:07'         UNION
      SELECT  91547     ,   '2018-08-26 04:59:07'         UNION
      SELECT  91582     ,   '2018-08-27 12:01:45'         UNION
      SELECT  91582     ,   '2018-08-26 19:01:45'


)


SELECT  *     FROM   (

SELECT  deviceid ,  readdate  ,   
readdate - (LAG(readdate, 1)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC) ) AS gap1  ,
LAG(readdate, 1)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC) AS  readdate_1down  ,
(LAG(readdate, 1)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC)) - (LAG(readdate, 2)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC))    AS   gap2  ,
LAG(readdate, 2)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC) AS  readdate_2down ,
(LAG(readdate, 2)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC)) - (LAG(readdate, 3)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC))    AS   gap3  ,
LAG(readdate, 3)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC) AS  readdate_3down  ,
(LAG(readdate, 3)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC)) - (LAG(readdate, 4)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC))    AS   gap4  ,
LAG(readdate, 4)  OVER (PARTITION BY deviceid  ORDER BY  readdate ASC) AS  readdate_4down
FROM  DEVICEID_TEST_DATA
-------WHERE   deviceid  =  91428

)
--------WHERE   gap1 = '01:00:00'  AND   gap2  =  '01:00:00'
ORDER BY  deviceid  ,  readdate DESC
...