您可以使用 Vertica 的 TIMESERIES 子句。
这是我完整的mkcalfromnothing.sql 脚本:
DROP TABLE IF EXISTS cal;
CREATE TABLE cal (
date_id INT NOT NULL
, date_dt DATE NOT NULL
, year_id SMALLINT NOT NULL
, yearquarter_id INTEGER NOT NULL
, quarter_nbr SMALLINT NOT NULL
, yearmonth_id INTEGER NOT NULL
, month_nbr SMALLINT NOT NULL
, month_name CHAR(10) NOT NULL
, day_of_month_nbr SMALLINT NOT NULL
, yearweek_id INTEGER NOT NULL
, week_nbr SMALLINT NOT NULL
, day_of_week_name VARCHAR(12) NOT NULL
, busday_flag BOOLEAN NOT NULL
, last_day_of_month_flag BOOLEAN NOT NULL
, last_day_of_quarter_flag BOOLEAN NOT NULL
);
INSERT INTO cal
WITH datelist AS (
SELECT dt::DATE AS dt
FROM (
SELECT TIMESTAMP '2009-01-01' ts
UNION ALL SELECT TIMESTAMP '2020-12-31' ts
) lims
TIMESERIES dt AS '1 DAY' OVER(ORDER BY ts)
)
SELECT
YEAR(dt)*10000+MONTH(dt)*100+DAY(dt) AS date_id
, dt AS date_dt
, YEAR(dt) AS year_id
, YEAR(dt) * 10 + QUARTER(dt) AS yearquarter_id
, QUARTER(dt) AS quarter_nbr
, YEAR(dt) * 100 + MONTH(dt) AS yearmonth_id
, MONTH(dt) AS month_nbr
, TO_CHAR(dt,'Month') AS month_name
, DAY(dt) AS day_of_month_nbr
, YEAR(dt)*10+WEEK(dt) AS yearweek_id
, WEEK(dt) AS week_nbr
, TO_CHAR(dt, 'Day') AS day_of_week_name
, DAYOFWEEK_ISO(dt) NOT IN (6,7) AS busday_flag
, DAY(dt+1)=1 AS last_day_of_month_flag
, DAY(dt+1)=1 AND MONTH(dt+1) IN (1,4,7,10) AS last_day_of_quarter_flag
FROM datelist;