您是否正在搜索可从中选择一个月的第一天和最后一天的视图?
这个将创建一个视图
months
CREATE VIEW months
AS
WITH RECURSIVE cte(i, number_of_year, number_of_month, first_day, last_day)
AS
(
SELECT 1 i,
0 / 12 + 1970 number_of_year,
0 % 12 + 1 number_of_month,
(lpad((0 / 12 + 1970)::text, 4, '0') || '-' || lpad((0 % 12 + 1)::text, 2, '0') || '-01')::timestamp first_day,
(lpad((0 / 12 + 1970)::text, 4, '0') || '-' || lpad((0 % 12 + 1)::text, 2, '0') || '-01')::timestamp + INTERVAL '1 month - 1 day' last_day
UNION ALL
SELECT i + 1 i,
i / 12 + 1970 number_of_year,
i % 12 + 1 number_of_month,
(lpad((i / 12 + 1970)::text, 4, '0') || '-' || lpad((i % 12 + 1)::text, 2, '0') || '-01')::timestamp first_day,
(lpad((i / 12 + 1970)::text, 4, '0') || '-' || lpad((i % 12 + 1)::text, 2, '0') || '-01')::timestamp + INTERVAL '1 month - 1 day' last_day
FROM cte
WHERE i / 12 + 1970 <= 2070
)
SELECT number_of_year,
number_of_month,
first_day,
last_day
FROM cte;
但我建议将其具体化以获得更好的性能。
CREATE TABLE months
AS
WITH RECURSIVE cte(i, number_of_year, number_of_month, first_day, last_day)
AS
(
SELECT 1 i,
0 / 12 + 1970 number_of_year,
0 % 12 + 1 number_of_month,
(lpad((0 / 12 + 1970)::text, 4, '0') || '-' || lpad((0 % 12 + 1)::text, 2, '0') || '-01')::timestamp first_day,
(lpad((0 / 12 + 1970)::text, 4, '0') || '-' || lpad((0 % 12 + 1)::text, 2, '0') || '-01')::timestamp + INTERVAL '1 month - 1 day' last_day
UNION ALL
SELECT i + 1 i,
i / 12 + 1970 number_of_year,
i % 12 + 1 number_of_month,
(lpad((i / 12 + 1970)::text, 4, '0') || '-' || lpad((i % 12 + 1)::text, 2, '0') || '-01')::timestamp first_day,
(lpad((i / 12 + 1970)::text, 4, '0') || '-' || lpad((i % 12 + 1)::text, 2, '0') || '-01')::timestamp + INTERVAL '1 month - 1 day' last_day
FROM cte
WHERE i / 12 + 1970 <= 2070
)
SELECT number_of_year,
number_of_month,
first_day,
last_day
FROM cte;
我想你会这样问:
SELECT first_day,
last_day
FROM months
WHERE number_of_year = <year>
AND number_of_month = <month>;
然后还创建以下索引来支持它。
CREATE INDEX months_number_of_year_number_of_month_first_day_last_day
ON months (number_of_year,
number_of_month,
first_day,
last_day);