#sql #amazon-redshift
#sql #amazon-redshift
Вопрос:
У меня есть запрос, который может создать таблицу с датами, как показано ниже:
with digit as (
select 0 as d union all
select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9
),
seq as (
select a.d (10 * b.d) (100 * c.d) (1000 * d.d) as num
from digit a
cross join
digit b
cross join
digit c
cross join
digit d
order by 1
)
select (last_day(sysdate)::date - seq.num)::date as "Date"
from seq;
Как это можно изменить, чтобы генерировать только даты
Спасибо
Ответ №1:
WITH dates AS (
SELECT
date_trunc('month', CURRENT_DATE) AS first_day_of_month,
date_trunc('month', CURRENT_DATE) interval '1 month -1 day' AS last_day_of_month
)
SELECT
generate_series(first_day_of_month, last_day_of_month, interval '1 day')::date
FROM dates
date_trunc()
усекает типdate
(илиtimestamp
) до определенной части даты.date_trunc('month', ...)
удаляет все части, кромеyear
иmonth
. Для всех остальных частей устанавливаются минимально возможные значения. Итак,day
для части установлено значение1
. Вот почему вы получаете первый день месяца с этим.- добавление месяца возвращает первое число следующего месяца, вычитая из этого день, получается последний день текущего месяца.
- Наконец, вы можете сгенерировать ряд дат с начальной и конечной датой, используя
generate_series()
функцию
Редактировать: Redshift не поддерживает generate_series()
with type date
и timestamp
, но with integer
. Итак, вместо этого нам нужно создать integer
серию и добавить результаты к первому числу месяца:
WITH dates AS (
SELECT
date_trunc('month', CURRENT_DATE) AS first_day_of_month,
date_trunc('month', CURRENT_DATE) interval '1 month -1 day' AS last_day_of_month
)
SELECT
first_day_of_month::date gs
FROM
dates,
generate_series(
date_part('day', first_day_of_month)::int - 1,
date_part('day', last_day_of_month)::int - 1
) as gs
Комментарии:
1. @Adella добавил версию, совместимую с Redshift
2. Фух, на самом деле у меня нет экземпляра Redshift для тестирования… Может быть, это работает? dbfiddle.uk /… или это dbfiddle.uk /…
3. Это не работает? dbfiddle.uk /…
4. @Adella: В документах из Redshift говорится, что это должно сработать, если ВЫБОР заключен в параграфы: docs.aws.amazon.com/en_us/redshift/latest/dg/… Итак, может быть, это? dbfiddle.uk /…
5. Сделано @S-Man! Спасибо!!
Ответ №2:
Это отвечает на исходную версию вопроса.
Вы бы использовали generate_series()
:
select gs.dte
from generate_series(date_trunc('month', now()::date),
date_trunc('month', now()::date) interval '1 month' - interval '1 day',
interval '1 day'
) gs(dte);
Вот скрипка db<> .
Комментарии:
1. Generate_series () является функцией только ведущего узла в Redshift и не может использоваться для хранения данных в таблице. Это даст правильный результат, но поскольку запрос был направлен на способ создания таблицы, это не удовлетворит потребности.
2. @BillWeiner . , , Вопрос был помечен как Postgres — и только Postgres — когда я ответил на него.