Как генерировать ряды дат в Красном смещении

#sql #amazon-web-services #amazon-redshift

Вопрос:

Я хотел бы сгенерировать последовательность дат в красном смещении. Я могу легко сделать это в PostgreSQL, используя generate_series() функцию. Эта функция работает в Redshift, но только в главном узле, поэтому она не работает, когда вам нужно использовать ее во временных таблицах для применения некоторых соединений. Я нашел способ генерировать ряды дат в красном смещении следующим образом, но я ищу более эффективный способ.

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

  SELECT
  DATEADD('month', -n, DATE_TRUNC('month', add_months(CURRENT_DATE,12))) AS gdate
FROM (SELECT ROW_NUMBER() OVER () AS n FROM one_table LIMIT 200) n
 

введите описание изображения здесь

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

1. Рассмотрите такие инструменты, как таблицы чисел, таблицы календаря и т. Д. Сохраняя эти понятия в виде таблиц, вам просто нужно использовать соединение. Это может привести к упрощению кода, поиску с возможностью поиска (при красном смещении я обычно использую ВСЕ стили, ДЕЛЬТА КОДИРОВАНИЯ и т. Д. Для быстрого доступа) И множеству дополнительных преимуществ (таких как сохранение информации о банковских праздниках в таблицах календаря) . Использование и достоинства таких таблиц хорошо документированы в Интернете.

Ответ №1:

Вы можете использовать рекурсивный CTE (который теперь поддерживает Redshift). Вы можете сгенерировать даты напрямую:

 with recursive months (yyyymm, n) as (
      select date_trunc('month', current_date) as yyyymm, 1 as n
      union all
      select yyyymm - interval '1 month', n   1
      from months m
      where n < 200
     )
select yyyymm
from months;
 

Ответ №2:

Используйте рекурсивный подзапрос (предложение CTE/with):

 with recursive numbers(NUMBER) as
(
select 1 UNION ALL
select NUMBER   1 from numbers where NUMBER < 200
),
somedates(thedate) as 
(
select DATEADD('month', -NUMBER, DATE_TRUNC('month',CURRENT_DATE)) AS gdate
from numbers
)