有一张桌子:日期存储在smallint字段中的节日(不是很优雅,我知道..)。 它看起来像是:
id - serial, PK
day - smallint NOT NULL,
month - smallint NOT NULL,
year - smallint
看起来很简单 - 如果有某个日期的记录,那个日期也会有某种盛宴。
“只有”一件事让整个想法变得复杂...... Field'ear'可以为空。如果'year'为null,那意味着当天有可移动的盛宴 - 与年份无关。 (当然我可以为date创建一个字段,并且一些布尔标志'is_movable',但它不会改变我的问题中的任何内容。)
我想创建一个程序来列出指定日期范围内的所有节日。
get_all_feasts(date_from date, date_to date)
..返回表:id,date,is_movable。
例如,对于数据:
id / day / month / year
1 / 12 / 05 / 2013
2 / 15 / 05 / 2013
3 / 16 / 02 / 2012
4 / 25 / 12 / NULL
5 / 26 / 12 / NULL
6 / 2 / 04 / 2014
..函数调用:get_all_feasts('2012-03-01':: date,'2014-05-01':: date) 应该回来:
id / date
4 / 2012-12-25
5 / 2012-12-26
1 / 2013-05-12
2 / 2013-05-15
4 / 2013-12-25
5 / 2013-12-26
6 / 2014-04-02
选择指定年份,月份和日期的节日没有问题。
但是如何为特定范围内的可移动节日生成节日?
我使用PostgreSQL v.9.2。
答案 0 :(得分:0)
您可以使用WITH RECURSIVE查询 - Reference
试试这个 -
WITH RECURSIVE year_table(n) AS (
SELECT 1000
UNION ALL
SELECT n+1 FROM year_table
)
SELECT Id, To_Date(DAY || ' ' || MONTH || ' ' || YEAR, 'DD MM YYYY')
FROM Feasts
WHERE To_Date(DAY || ' ' || MONTH || ' ' || YEAR, 'DD MM YYYY') >=
Date_From
AND To_Date(DAY || ' ' || MONTH || ' ' || YEAR, 'DD MM YYYY') <= Date_To
AND YEAR IS NOT NULL
UNION
SELECT Feasts.Id,
To_Date(DAY || ' ' || MONTH || ' ' || Year_Table.n, 'DD MM YYYY')
FROM Feasts, Year_Table
WHERE n >= To_Char(Date_From, 'YYYY')
AND n <= To_Char(Date_To, 'YYYY')
AND Feasts.YEAR IS NULL;
答案 1 :(得分:0)
SELECT
id, (coalesce(year, EXTRACT(YEAR FROM NOW())) || '-' || month || '-' || day) as date
FROM
feasts
WHERE
(coalesce(year, EXTRACT(YEAR FROM NOW())) || '-' || month || '-' || day)::date >= date_from
AND (coalesce(year, EXTRACT(YEAR FROM NOW())) || '-' || month || '-' || day)::date <= date_to
ORDER BY
(coalesce(year, EXTRACT(YEAR FROM NOW())) || '-' || month || '-' || day)::date, id;