Предложение WHERE в результате подзапроса всегда возвращает пустой набор

#sql #where-clause #clickhouse

#sql #предложение where #clickhouse

Вопрос:

Я вычисляю взвешенное скользящее среднее с помощью следующего оператора SELECT:

 SELECT ts_g as ts, runningAccumulate(tpv) / runningAccumulate(tvol) as vwap
FROM
(
    SELECT ts_g, sumState(pv) tpv, sumState(vol_per_price) tvol
    FROM (
        SELECT ts_g, close * vol_per_price as pv, sum(vol) as vol_per_price
        FROM tablename_here
        WHERE ts >= toDateTime64('2018-02-04 14:30:00.000000', 6, 'UTC')
          AND ts < toDateTime64('2019-02-27 23:59:00.000000', 6, 'UTC')
        GROUP BY toStartOfInterval(ts, INTERVAL 1 minute) AS ts_g, close
        ORDER BY ts_g ASC, close ASC
    )
    GROUP BY ts_g
    ORDER BY ts_g
)
  

Который выдает правильный результат (первые десять строк ниже):

 ┌──────────────────ts─┬──────vwap─┐
│ 2018-02-05 18:05:002742.0000 │
│ 2018-02-05 21:54:002706.3333 │
│ 2018-02-05 23:49:002686.0000 │
│ 2018-02-05 23:51:002675.8500 │
│ 2018-02-06 11:56:002664.8750 │
│ 2018-02-06 14:34:002660.6071 │
│ 2018-02-06 15:35:002658.6562 │
│ 2018-02-07 16:25:002667.4722 │
│ 2018-02-09 14:53:002663.2250 │
│ 2018-02-16 13:23:002671.6590 │
└─────────────────────┴───────────┘
  

Я хотел бы выбрать подмножество этого ответа следующим образом:

 SELECT ts, vwap
FROM ( original query here )
WHERE ts >= toDateTime64('some start date', 6, 'UTC')
  AND ts < toDateTime64('some end date', 6, 'UTC')
ORDER BY ts
  

Однако это всегда возвращает 0 rows in set , даже если диапазон дат в предложении WHERE идентичен или шире исходного. Я делаю это неправильно или это ошибка в clickhouse?

Версии: ClickHouse server version 20.6.3.28 (official build).
ClickHouse client version 20.6.3.28 (official build).

Ответ №1:

Вы пытаетесь сравнить DateTime с DateTime64, что неявно приводит к применению числового сравнения.

Для этого необходимо либо явно преобразовать DateTime в DateTime64 (что не имеет смысла для минутного интервала):

 SELECT ts, vwap
FROM ( original query here )
WHERE toDateTime64(ts, 6, 'UTC') >= toDateTime64('some start date', 6, 'UTC')
  AND toDateTime64(ts, 6, 'UTC') < toDateTime64('some end date', 6, 'UTC')
ORDER BY ts
  

или используйте в предложении WHERE значение DateTime:

 SELECT ts, vwap
FROM ( original query here )
WHERE ts >= toDateTime('some start date', 'UTC')
  AND ts < toDateTime('some end date', 'UTC')
ORDER BY ts
  

Я добавил проблему CH: Сравнение DateTime64 с DateTime / Date, связанную с запутанным поведением этого сравнения.

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

1. Вот и все, спасибо, что указали на это! Что касается проблемы, которую вы открыли, я думаю, что предупреждение / исключение было бы лучшим. Технически поведение правильное, просто оно не очень очевидно.