Эффективный способ получить строки сразу за пределами временного окна - PullRequest
0 голосов
/ 05 марта 2020

У нас есть данные временных рядов, хранящиеся в таблице clickhouse, например:

timestamp             value
2020-03-05 11:03:00    2
2020-03-05 11:12:00    3
2020-03-05 11:13:00    4
2020-03-05 11:27:00    5
2020-03-05 11:31:00    6
2020-03-05 11:39:00    7

При визуализации этих данных мы запрашиваем временной диапазон, например 2020-03-05 11:15:00 - 2020-03-05 11:30:00.

В этом диапазоне легко выбрать данные, но что более полезно для визуализации, так это получить точки с обеих сторон, например:

2020-03-05 11:12:00    3
2020-03-05 11:13:00    4
2020-03-05 11:27:00    5
2020-03-05 11:31:00    6

Есть ли эффективный способ сделать это в кликхаусе? На данный момент я делаю (потенциально) 3 отдельных запроса:

  1. Выбор данных в диапазоне:
select * from data where timestamp >= "from" and timestamp <= "to" order by timestamp
Если отметка времени первой точки! = Отметка времени "от":
select * from data where timestamp < "from" order by timestamp desc limit 1
Если отметка времени последней точки! = Отметка времени "к":
select * from data where timestamp > "to" order by timestamp limit 1

Было бы замечательно получить ее в одном запросе.

Ответы [ 2 ]

0 голосов
/ 06 марта 2020

Я бы расширил диапазон с помощью некоторой функции toStartOfTenMinutes ('2020-03-05 11:15:00) toStartOfTenMinutes (' 2020-03-05 11:30:00 ') + 600 или -600 + 600

И отфильтровывать лишние строки на стороне клиента. Потому что 3 запроса медленнее, чем 1.

0 голосов
/ 06 марта 2020

Похоже, нужно просто объединить все три запроса в один и немного изменить операторы сравнения:

SELECT * 
FROM (
  SELECT *
  FROM
  (
      /* test data */
      SELECT data.1 AS timestamp, data.2 AS value
      FROM (SELECT arrayJoin([(toDateTime('2020-03-05 11:03:00'), 2), (toDateTime('2020-03-05 11:12:00'), 3), (toDateTime('2020-03-05 11:13:00'), 4), (toDateTime('2020-03-05 11:27:00'), 5), (toDateTime('2020-03-05 11:31:00'), 6), (toDateTime('2020-03-05 11:39:00'), 7)]) AS data)
  )
  WHERE timestamp > '2020-03-05 11:15:00' AND timestamp < '2020-03-05 11:30:00'
  UNION ALL
  SELECT DISTINCT *
  FROM (
    SELECT *
    FROM
    (
        /* test data */
        SELECT data.1 AS timestamp, data.2 AS value
        FROM (SELECT arrayJoin([(toDateTime('2020-03-05 11:03:00'), 2), (toDateTime('2020-03-05 11:12:00'), 3), (toDateTime('2020-03-05 11:13:00'), 4), (toDateTime('2020-03-05 11:27:00'), 5), (toDateTime('2020-03-05 11:31:00'), 6), (toDateTime('2020-03-05 11:39:00'), 7)]) AS data)
    )
    WHERE timestamp <= '2020-03-05 11:15:00'
    ORDER BY timestamp DESC
    LIMIT 1
    UNION ALL
    SELECT *
    FROM
    (
        /* test data */
        SELECT data.1 AS timestamp, data.2 AS value
        FROM (SELECT arrayJoin([(toDateTime('2020-03-05 11:03:00'), 2), (toDateTime('2020-03-05 11:12:00'), 3), (toDateTime('2020-03-05 11:13:00'), 4), (toDateTime('2020-03-05 11:27:00'), 5), (toDateTime('2020-03-05 11:31:00'), 6), (toDateTime('2020-03-05 11:39:00'), 7)]) AS data)
    )
    WHERE timestamp >= '2020-03-05 11:30:00'
    ORDER BY timestamp ASC
    LIMIT 1))
ORDER BY timestamp;
/* result
┌───────────timestamp─┬─value─┐
│ 2020-03-05 11:13:00 │     4 │
│ 2020-03-05 11:27:00 │     5 │
│ 2020-03-05 11:31:00 │     6 │
└─────────────────────┴───────┘
*/
..
WHERE timestamp > '2020-03-05 11:13:00' AND timestamp < '2020-03-05 11:30:00'
..
/* result
┌───────────timestamp─┬─value─┐
│ 2020-03-05 11:13:00 │     4 │
│ 2020-03-05 11:27:00 │     5 │
│ 2020-03-05 11:31:00 │     6 │
└─────────────────────┴───────┘
*/ 
..
WHERE timestamp > '2020-03-05 11:15:00' AND timestamp < '2020-03-05 11:31:00'
..
/* result
┌───────────timestamp─┬─value─┐
│ 2020-03-05 11:13:00 │     4 │
│ 2020-03-05 11:27:00 │     5 │
│ 2020-03-05 11:31:00 │     6 │
└─────────────────────┴───────┘
*/
..
WHERE timestamp > '2020-03-05 11:27:00' AND timestamp < '2020-03-05 11:31:00'
..
/* result
┌───────────timestamp─┬─value─┐
│ 2020-03-05 11:27:00 │     5 │
│ 2020-03-05 11:31:00 │     6 │
└─────────────────────┴───────┘
*/
..
WHERE timestamp > '2020-03-05 11:28:00' AND timestamp < '2020-03-05 11:28:00'
..
/* result
┌───────────timestamp─┬─value─┐
│ 2020-03-05 11:27:00 │     5 │
│ 2020-03-05 11:31:00 │     6 │
└─────────────────────┴───────┘
*/
..
WHERE timestamp > '2020-03-05 11:31:00' AND timestamp < '2020-03-05 11:31:00'
..
/*
result
┌───────────timestamp─┬─value─┐
│ 2020-03-05 11:31:00 │     6 │
└─────────────────────┴───────┘
*/
...