Я работаю с базой данных Vertica, и мне нужно было сделать запрос, который, учитывая две даты, предоставит мне список всех месяцев между указанными датами. Например, если бы я, чтобы дать запрос 2015-01-01 и 2015-12-31, он будет выводить меня следующий список:Вертикальная дата-серия начинается за месяц до указанной даты
2015-01-01
2015-02-01
2015-03-01
2015-04-01
2015-05-01
2015-06-01
2015-07-01
2015-08-01
2015-09-01
2015-10-01
2015-11-01
2015-12-01
После немного копать, я смог обнаружить следующее запрос:
SELECT date_trunc('MONTH', ts)::date as Mois
FROM
(
SELECT '2015-01-01'::TIMESTAMP as tm
UNION
SELECT '2015-12-31'::TIMESTAMP as tm
) as t
TIMESERIES ts as '1 month' OVER (ORDER BY tm)
Этот запрос работает и дает мне следующий вывод:
2014-12-01
2015-01-01
2015-02-01
2015-03-01
2015-04-01
2015-05-01
2015-06-01
2015-07-01
2015-08-01
2015-09-01
2015-10-01
2015-11-01
2015-12-01
Как вы можете видеть, давая запрос, отправную дату «2015-01-01» или где-нибудь в январе для этого важно, чтобы я закончил с ext ra, а именно 2014-12-01. Сама по себе ошибка (или то, что вы хотите назвать этим неожиданным поведением) легко обойти (только начать в феврале), но я должен признать, что мой любопытство покорился. Почему именно сериал начинается через месяц до даты, указанной мной?
EDIT: Хорошо, прочитав предупреждение Кимбо и подтвердив, что действительно, длительные периоды в конечном итоге вызовут проблемы, я смог выработать следующий запрос, который правильно корректирует даты.
SELECT ts as originalMonth,
ts +
(
mod
(
day(first_value(ts) over (order by ts)) - day(ts) + day(last_day(ts)),
day(last_day(ts))
)
) as adjustedMonth
FROM
(
SELECT ts
FROM
(
SELECT '2015-01-01'::TIMESTAMP as tm
UNION
SELECT '2018-12-31'::TIMESTAMP as tm
) as t
TIMESERIES ts as '1 month' OVER (ORDER BY tm)
) as temp
Единственная проблема у меня есть, что я не имею никакого контроля над начальным днем первой записи серии. Он устанавливается автоматически Vertica в текущий день. Поэтому, если я запустил этот запрос 31-го числа месяца, мне интересно, как он будет себя вести. Думаю, мне просто нужно ждать декабря, если кто-то не знает, как заставить таймеры вести себя таким образом, чтобы я мог ее протестировать.
EDIT: Хорошо, поэтому, опробовав множество разных комбинаций дат, я смог определить, что день, который начинается в серии, зависит от указанной вами даты. Это вызвало массу проблем ... пока мы не решили пойти простым путем. Вместо использования месячного интервала мы использовали дневной интервал и выбирали только один конкретный день в месяц. ПУТЬ проще, и он работает все время. Вот окончательный запрос:
SELECT ts as originalMonth
FROM
(
SELECT ts
FROM
(
SELECT '2000-02-01'::TIMESTAMP as tm
UNION
SELECT '2018-12-31'::TIMESTAMP as tm
) as t
TIMESERIES ts as '1 day' OVER (ORDER BY tm)
) as temp
where day(ts) = 1
Вы должны создать [таблицу календаря] (http://vertica.tips/2014/07/17/creating-a-numbers-and-calendar-table/), в противном случае доступно SQL-решение [здесь] (http://vertica-forums.com/viewtopic.php?p=7223#p7223). – Kermit
Спасибо Кермит, но это было не то, о чем я просил. Я спрашивал о дополнительном «2014-12-01», который появляется в начале списка. Как бы то ни было, проблема, вызвавшая необходимость создания этого запроса, уже решена. – Osuwariboy