-- Use or create database (adjust as needed)
-- \c test;
DROP TABLE IF EXISTS calendar_basic;
CREATE TABLE calendar_basic (
date_id INT NOT NULL PRIMARY KEY,
full_date DATE NOT NULL,
date_name VARCHAR(10) NOT NULL,
year_month INT,
year_week INT,
yqmd VARCHAR(10) NOT NULL,
day_of_week INT NOT NULL,
day_of_week_name VARCHAR(10) NOT NULL,
day_of_month INT NOT NULL,
month_name VARCHAR(10) NOT NULL,
month_abbr VARCHAR(3) NOT NULL,
day_of_year INT NOT NULL,
is_week_day BOOLEAN NOT NULL,
is_weekend_day BOOLEAN NOT NULL,
is_holiday BOOLEAN NOT NULL,
week_of_year INT NOT NULL,
month_of_year INT NOT NULL,
is_last_day_of_month BOOLEAN NOT NULL,
calendar_quarter INT NOT NULL,
calendar_semester INT NOT NULL,
calendar_year INT NOT NULL,
fiscal_month_of_year INT NOT NULL,
fiscal_quarter INT NOT NULL,
fiscal_semester INT NOT NULL,
fiscal_year INT NOT NULL
);
DO $$
DECLARE
process_date DATE;
BEGIN
process_date := '2000-01-01'::DATE;
WHILE process_date <= '2030-12-31'::DATE LOOP
INSERT INTO calendar_basic (
date_id,
full_date,
date_name,
year_month,
year_week,
yqmd,
day_of_week,
day_of_week_name,
day_of_month,
month_name,
month_abbr,
day_of_year,
is_week_day,
is_weekend_day,
is_holiday,
week_of_year,
month_of_year,
is_last_day_of_month,
calendar_quarter,
calendar_semester,
calendar_year,
fiscal_month_of_year,
fiscal_quarter,
fiscal_semester,
fiscal_year
)
SELECT
TO_CHAR(process_date, 'YYYYMMDD')::INT AS date_id,
process_date AS full_date,
TO_CHAR(process_date, 'YYYY-MM-DD') AS date_name,
TO_CHAR(process_date, 'YYYYMM')::INT AS year_month,
(TO_CHAR(process_date, 'YYYY') || LPAD(EXTRACT(WEEK FROM process_date)::TEXT, 2, '0'))::INT AS year_week,
(TO_CHAR(process_date, 'YYYY') || '0' || EXTRACT(QUARTER FROM process_date)::TEXT ||
LPAD(EXTRACT(MONTH FROM process_date)::TEXT, 2, '0') ||
LPAD(EXTRACT(DAY FROM process_date)::TEXT, 2, '0'))::VARCHAR(10) AS yqmd,
EXTRACT(ISODOW FROM process_date)::INT AS day_of_week,
TO_CHAR(process_date, 'Day')::VARCHAR(10) AS day_of_week_name,
EXTRACT(DAY FROM process_date)::INT AS day_of_month,
TO_CHAR(process_date, 'Month')::VARCHAR(10) AS month_name,
TO_CHAR(process_date, 'Mon')::VARCHAR(3) AS month_abbr,
EXTRACT(DOY FROM process_date)::INT AS day_of_year,
CASE
WHEN EXTRACT(ISODOW FROM process_date) NOT IN (6, 7) THEN TRUE
ELSE FALSE
END AS is_week_day,
CASE
WHEN EXTRACT(ISODOW FROM process_date) IN (6, 7) THEN TRUE
ELSE FALSE
END AS is_weekend_day,
FALSE AS is_holiday,
EXTRACT(WEEK FROM process_date)::INT AS week_of_year,
EXTRACT(MONTH FROM process_date)::INT AS month_of_year,
CASE
WHEN EXTRACT(MONTH FROM process_date) <> EXTRACT(MONTH FROM process_date + INTERVAL '1 day') THEN TRUE
ELSE FALSE
END AS is_last_day_of_month,
EXTRACT(QUARTER FROM process_date)::INT AS calendar_quarter,
CASE
WHEN EXTRACT(MONTH FROM process_date) < 7 THEN 1
ELSE 2
END AS calendar_semester,
EXTRACT(YEAR FROM process_date)::INT AS calendar_year,
EXTRACT(MONTH FROM process_date)::INT AS fiscal_month_of_year,
EXTRACT(QUARTER FROM process_date)::INT AS fiscal_quarter,
CASE
WHEN EXTRACT(MONTH FROM process_date) < 7 THEN 1
ELSE 2
END AS fiscal_semester,
EXTRACT(YEAR FROM process_date)::INT AS fiscal_year;
process_date := process_date + INTERVAL '1 day';
END LOOP;
END $$;
-- Test query
SELECT *
FROM calendar_basic
WHERE date_id >= 20260101
ORDER BY date_id
LIMIT 1;