time_bucket_gapfill возвращает пустой результат, если отсутствуют необработанные данные

#timescaledb

#timescaledb

Вопрос:

У меня есть следующий набор данных

 timeseries=# select * from ts_values where id = '32:6:1000001[2230041747,1346634600,]' limit 10;
             time              |                  id                  | value | type | quality
------------------------------- -------------------------------------- ------- ------ ---------
 2020-12-17 13:59:56.503654 00 | 32:6:1000001[2230041747,1346634600,] |     1 | x01 |
 2020-12-17 13:59:52.472668 00 | 32:6:1000001[2230041747,1346634600,] |     0 | x01 |
 2020-12-17 13:59:48.472304 00 | 32:6:1000001[2230041747,1346634600,] |     1 | x01 |
 2020-12-17 13:59:44.472265 00 | 32:6:1000001[2230041747,1346634600,] |     0 | x01 |
 2020-12-17 13:59:40.472345 00 | 32:6:1000001[2230041747,1346634600,] |     1 | x01 |
 2020-12-17 13:59:36.472545 00 | 32:6:1000001[2230041747,1346634600,] |     0 | x01 |
 2020-12-17 13:59:32.472802 00 | 32:6:1000001[2230041747,1346634600,] |     1 | x01 |
 2020-12-17 13:59:28.472272 00 | 32:6:1000001[2230041747,1346634600,] |     0 | x01 |
 2020-12-17 13:59:24.457489 00 | 32:6:1000001[2230041747,1346634600,] |     1 | x01 |
 2020-12-17 13:59:20.456482 00 | 32:6:1000001[2230041747,1346634600,] |     0 | x01 |
(10 rows)
 

Я пытаюсь использовать time_bucket_gapfill для этих данных, но я вижу какое-то поведение, которое я не понимаю.

Сначала пример, который работает:

 timeseries=# SELECT
timeseries-#   time_bucket_gapfill(INTERVAL '1 second', time) as time1s,
timeseries-#   id,
timeseries-#   locf(min(value), (SELECT value FROM ts_values where time < '2020-12-17 13:59:40' AND id = FOO.id order by time desc limit 1)) AS locf_value
timeseries-# FROM ts_values as FOO
timeseries-# WHERE
timeseries-#   time > '2020-12-17 13:59:40'
timeseries-#   AND time < '2020-12-17 13:59:44'
timeseries-#   AND id = '32:6:1000001[2230041747,1346634600,]'
timeseries-# GROUP BY 1,2;
         time1s         |                  id                  | locf_value
------------------------ -------------------------------------- ------------
 2020-12-17 13:59:40 00 | 32:6:1000001[2230041747,1346634600,] |          1
 2020-12-17 13:59:41 00 | 32:6:1000001[2230041747,1346634600,] |          1
 2020-12-17 13:59:42 00 | 32:6:1000001[2230041747,1346634600,] |          1
 2020-12-17 13:59:43 00 | 32:6:1000001[2230041747,1346634600,] |          1
 

пока в диапазоне gapfill есть точки данных, он создает данные, но, как показано ниже,
если в диапазоне отсутствуют данные, он ничего не создает.

 timeseries=# SELECT
timeseries-#   time_bucket_gapfill(INTERVAL '1 second', time) as time1s,
timeseries-#   id,
timeseries-#   locf(min(value), (SELECT value FROM ts_values where time < '2020-12-17 13:59:41' AND id = FOO.id order by time desc limit 1)) AS locf_value
timeseries-# FROM ts_values as FOO
timeseries-# WHERE
timeseries-#   time > '2020-12-17 13:59:41'
timeseries-#   AND time < '2020-12-17 13:59:43'
timeseries-#   AND id = '32:6:1000001[2230041747,1346634600,]'
timeseries-# GROUP BY 1,2;
 time1s | id | locf_value
-------- ---- ------------
(0 rows)
 

разве time_bucket_gapfill не должен выдавать данные с указанным разрешением, несмотря ни на что?

Ответ №1:

time_bucket_gapfill необходимо знать возможное значение группировки, чтобы иметь возможность заполнить пробел. Он использует фактические данные, возвращаемые запросом перед применением gapfill . Итак, для рассматриваемого запроса это будет что-то вроде:

 SELECT
  time_bucket(INTERVAL '1 second', time) as time1s,
  id,
  locf(min(value), (SELECT value FROM ts_values where time < '2020-12-17 13:59:41' AND id = FOO.id order by time desc limit 1)) AS locf_value
FROM ts_values as FOO
WHERE
  time > '2020-12-17 13:59:41'
  AND time < '2020-12-17 13:59:43'
  AND id = '32:6:1000001[2230041747,1346634600,]'
GROUP BY 1,2;
 

Я предлагаю проверить фактическое EXPLAIN значение для запроса gapfill.

В запросе вопроса есть два столбца группировки: time_bucket_gapfill(INTERVAL '1 second', time) as time1s и id . time_bucket_gapfill вычисляет возможные значения для time1s на основе его аргументов и временного интервала, полученного из предложения WHERE . Однако он не может вычислить возможные значения для id , поскольку запрос не возвращает никаких результатов, т.Е. Набор группирующих значений для id пуст, что приводит к пустому результату.

РЕДАКТИРОВАТЬ Возможно несколько решений, но каждое из них будет предоставлять различную семантику.

  1. Удалите второй столбец группировки, что приведет к заполнению пробелов каждую секунду. Результатом locf_value будет NULL, поскольку подзапрос возвращает пустой результат из-за отсутствия выбранных записей FOO .
  2. Увеличьте диапазон данных, чтобы включить некоторые данные.
  3. Увеличьте диапазон данных, как в 2, но явно укажите начало и конец time_bucket_gapfill , чтобы записи с пробелами были только для целевого диапазона.

Комментарии:

1. Но если я удалю идентификатор, locf не будет работать.

2. @schultz Ваш подзапрос в locf вернет null, поскольку нет записей FOO , удовлетворяющих внешнему условию. Это не связано с группировкой по id .