Динамическая таблица дат

Я создаю модель данных в PowerPivot, и мне интересно, могу ли я создать динамическую таблицу дат в SQL. Мне удалось создать его в PowerQuery, однако есть некоторые ошибки в PowerQuery (соединение только для чтения), когда таблица изменяется в PowerPivot. То, что я ищу, - это иметь дату начала 01.01.2013 (интервал - дни), и по мере того, как каждый новый год катится вокруг, строки добавляются в таблицу дат. Есть какой-либо способ сделать это?

Я использую Postgres

До сих пор я придумал это,

SELECT * FROM dbo.fof_GetDates('1/1/2013', GETDATE())

Но я хочу, чтобы он отображал все даты до конца года.


person Jason    schedule 24.06.2015    source источник
comment
Какую СУБД вы используете? Постгрес? Оракул?   -  person a_horse_with_no_name    schedule 24.06.2015
comment
@ a_horse_with_no_name см. редактирование. Спасибо   -  person Jason    schedule 24.06.2015


Ответы (1)


Полностью динамический подход представляет собой запрос, основанный на generate_series():

SELECT the_date::date
FROM   generate_series('2013-01-01 0:0'::timestamp
                     , date_trunc('year', now()::timestamp)
                                    + interval '1 year - 1 day'
                     , interval '1 day') the_date;
  • Всегда используйте формат ISO 8601 для дат и меток времени, который работает независимо от региональных настроек.

  • Окончательное приведение к date (the_date::date), потому что функция возвращает timestamp (при подаче timestamp аргументов).

  • Выражение

    date_trunc('year', now()::timestamp) + interval '1 year - 1 day'
    

    вычисляет последний день текущего года. В качестве альтернативы вы можете использовать EXTRACT (year FROM now())::text || '-12-31')::date, но это медленнее.

Вы можете обернуть это в пользовательскую "табличную функцию" (также известную как set-returning function), которую вы можете в основном использовать в качестве замены имени таблицы в запросах:

CREATE OR REPLACE FUNCTION f_dates_since_2013()
  RETURNS SETOF date AS
$func$
SELECT the_date::date
FROM   generate_series('2013-01-01 0:0'::timestamp
                     , date_trunc('year', now()::timestamp)
                                    + interval '1 year - 1 day'
                     , interval '1 day') the_date;
$func$  LANGUAGE sql STABLE;

Пример:

SELECT * FROM f_dates_since_2013();

Сделав еще один шаг, вы можете создать таблицу или, что более элегантно, < strong>MATERIALIZED VIEW на основе этой функции (или непосредственно базового запроса):

CREATE MATERIALIZED VIEW my_dates(the_date) AS
SELECT * FROM f_dates_since_2013();

Вызов:

SELECT * FROM my_dates;

Все, что вам нужно сделать сейчас, это запланировать ежегодное задание cron, которое запустит REFRESH MATERIALIZED VIEW в начале каждого нового года:

REFRESH MATERIALIZED VIEW my_dates;
person Erwin Brandstetter    schedule 24.06.2015