Получить последнее значение ДО указанного промежутка времени - PullRequest
1 голос
/ 07 ноября 2019

Скажем, у меня есть простая таблица в Oracle, которая выглядит следующим образом:

Timestamp            TagName          TagValue
----------------------------------------------
2019.11.07 00:05:11  Tag1             1.0
2019.11.07 00:05:12  Tag1             11.2
2019.11.07 00:05:35  Tag2             23.0
2019.11.07 00:06:36  Tag1             0.56
2019.11.07 00:06:11  Tag2             23.6
2019.11.07 00:07:56  Tag2             11.2
2019.11.07 00:08:01  Tag1             123.05
2019.11.07 00:22:35  Tag2             8.13

В таблице хранятся данные за 3 года, и некоторые теги меняются часто, а некоторые очень редко.

Мне нужно запросить все строки «Tag1» для определенного временного диапазона, но мне также нужно получить ПОСЛЕДНЕЕ значение «Tag1» ПЕРЕД моим временным диапазоном.

Что-то вроде этого достаточно легко, чтобы дать мне все изменения «Tag1» с помощьювременной интервал (2019.11.07 00:06:00 - 2019.11.07 00:07:00):

SELECT *
FROM MyTable
WHERE
  Tagname LIKE 'Tag1'
AND
  (TS BETWEEN
      to_timestamp('2019.11.07 00:06:00.000000', 'YYYY.MM.DD HH24:MI:SS.FF')
  AND
      to_timestamp('2037.11.07 00:07:00.000000', 'YYYY.MM.DD HH24:MI:SS.FF')
  )

Но есть ли способ как-то изменить LAST Tag1 ДО диапазона? Поэтому в этом случае мне нужно получить эту строку: 2019.11.07 00:05:12 Tag1 11.2 (на самом деле эта строка может быть за несколько секунд до или за несколько месяцев до того, или, возможно, вообще не существовать)

Ответы [ 2 ]

1 голос
/ 07 ноября 2019

Вы можете использовать аналитическую функцию LEAD следующим образом:

SELECT * FROM
    (
        SELECT LEAD(T.TS) OVER(
                PARTITION BY T.TAG -- REMOVE "PARTITION BY" CLAUSE IF YOU ALWAYS  WANT TO WORK WITH SINGLE TAG 
                ORDER BY T.TS ) AS L_TS,
            T.* 
        FROM MYTABLE T
        WHERE T.TAGNAME = 'Tag1'
    )
WHERE
    ( TS BETWEEN TO_TIMESTAMP('2019.11.07 00:06:00.000000', 'YYYY.MM.DD HH24:MI:SS.FF') 
         AND TO_TIMESTAMP('2037.11.07 00:07:00.000000', 'YYYY.MM.DD HH24:MI:SS.FF') )
    OR ( L_TS BETWEEN TO_TIMESTAMP('2019.11.07 00:06:00.000000', 'YYYY.MM.DD HH24:MI:SS.FF') 
              AND TO_TIMESTAMP('2037.11.07 00:07:00.000000', 'YYYY.MM.DD HH24:MI:SS.FF') );

Cheers !!

0 голосов
/ 07 ноября 2019

Одной из возможностей является использование подзапроса и получение максимальной временной отметки ниже, чем время запуска, и используйте ее в своем внешнем запросе. Дополнительное использование NVL даст желаемые данные, если такой записи не существует:

SELECT *
FROM MyTable
WHERE
  Tagname = 'Tag1'
AND
  (TS BETWEEN
      NVL((SELECT MAX(TS) FROM MyTable
           WHERE Tagname = 'Tag1'
             AND TS < to_timestamp('2019.11.07 00:06:00.000000', 'YYYY.MM.DD HH24:MI:SS.FF')))
          ,to_timestamp('2019.11.07 00:06:00.000000', 'YYYY.MM.DD HH24:MI:SS.FF'))
  AND
      to_timestamp('2037.11.07 00:07:00.000000', 'YYYY.MM.DD HH24:MI:SS.FF')
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...