Получите результаты за 1 год от TimescaleDB - PullRequest
2 голосов
/ 22 апреля 2019

У меня есть таблица с данными для IoT-устройств, отправляющая измерения каждый час. Нужно получать отчеты за сегодня, неделю, месяц и год.

Используя timescaleDB, я получил некоторые "хорошие" результаты за сегодня, неделю и месяц. Например Ежемесячно:

   SELECT
      time_bucket('4 weeks', measured_at) AS month,
      MAX(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) - MIN(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) as consumption
      FROM readings
      WHERE device_id = 4
      GROUP BY month
      ORDER BY month DESC LIMIT 12;

Но не можете найти хороший способ получения значений по годам? Кто-нибудь когда-нибудь пробовал это?

Год не поддерживается в масштабе времени, использование недель приводит к неверному результату.

ОШИБКА: интервал, определенный в терминах месяца, года, века и т. Д., Не поддерживается

Ответы [ 2 ]

3 голосов
/ 22 апреля 2019

Пожалуйста, убедитесь, что вы знаете, какие данные вы на самом деле агрегируете с time_bucket:

TIMESTAMPTZ сгруппированы по времени в UTC.Таким образом, выравнивание ведер происходит по времени UTC.Одним из следствий этого является то, что ежедневные сегменты выровнены по полуночи UTC, а не по местному времени.

Как уже указывалось @TmTron, фактической верной версией для месяцев и лет будет использование date_trunc в качествеследует:

SELECT
    date_trunc('month', measured_at) AS month,
    MAX(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) - MIN(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) as consumption
    FROM readings
    WHERE device_id = 4
    GROUP BY 1
    ORDER BY 1 DESC LIMIT 12;

... и:

SELECT
    date_trunc('year', measured_at) AS year,
    MAX(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) - MIN(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) as consumption
    FROM readings
    WHERE device_id = 4
    GROUP BY 1
    ORDER BY 1 DESC LIMIT ...;

И если вы выбираете только определенный интервал (например, последние 12 месяцев), пожалуйста, всегда добавьтекритерии уменьшения количества сканируемых разделов, например:

SELECT
    date_trunc('month', measured_at) AS month,
    MAX(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) - MIN(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) as consumption
    FROM readings
    WHERE device_id = 4
        AND measured_at >= CURRENT_TIMESTAMP - '13 months'::interval
    GROUP BY 1
    ORDER BY 1 DESC LIMIT 12;
2 голосов
/ 22 апреля 2019

на данный момент time_bucket не поддерживает месяц / год: см. # 414

time_bucket разработан для регулярных интервалов, таких как дни, часы, минут. Поскольку месяцы и годы являются переменными единицами времени, функция не поддерживает их

postgres date_trunc также поддерживает месяц / год

...