Изменить диапазон дат на новые строки с дискретными датами
У меня есть таблица, которая содержит name
, location
, start_date
, а также end_date
, Я пытаюсь преобразовать эти строки, содержащие диапазоны дат, в строки отдельных дат, сохраняя при этом информацию о соответствующей строке.
Пример:
Name1, Location1, 2015-4-01, 2015-4-04
становится:
Name1, Location1, 2015-4-01
Name1, Location1, 2015-4-02
Name1, Location1, 2015-4-03
Name1, Location1, 2015-4-04
Я предполагаю, что мне нужно будет создать это как новую таблицу, используя функции PostgreSQL.
2 ответа
Создайте новую таблицу с тремя обязательными столбцами:
CREATE TABLE new_tbl (
nam varchar,
loc varchar,
dt date);
Поскольку вы хотите иметь записи в новой таблице в диапазоне start_date
- end_date
с дневным интервалом включительно самое простое решение - создать набор из ваших дат:
generate_series(start_date::timestamp, end_date::timestamp, '1 day')
Это вы можете просто придерживаться INSERT
выписка по новой таблице:
INSERT INTO new_tbl
SELECT nam, loc, generate_series(start_date::timestamp, end_date::timestamp, '1 day')::date
FROM old_tbl;
Так как generate_series
функция работает с timestamp
параметры, вам нужно явно привести ваш date
с, а затем разыграть сгенерированный timestamp
назад к date
s, чтобы соответствовать вашему определению столбца.
В современных Postgres (9.3+) лучше всего использовать функции, возвращающие множество в LATERAL
присоединиться к FROM
список:
Если предположить, start_date
а также end_date
определены NOT NULL
:
CREATE TABLE AS
SELECT name, location, day::date
FROM tbl, generate_series(start_date, end_date, interval '1 day') day;
LATERAL
здесь подразумевается.
Руководство о LATERAL
подзапросы.
Некоторые связанные ответы (есть много):
- Generate_series в Postgres от начальной и конечной даты в таблице
- Рассчитать рабочее время между 2 датами в PostgreSQL
Около LATERAL
(в ответ на комментарий):