1

有一张桌子:日期存储在 smallint 字段中的盛宴(我知道这不是优雅的方式..)。它看起来像这样:

id - serial, PK
day - smallint NOT NULL,
month - smallint NOT NULL,
year - smallint

看起来很简单——如果有某个日期的记录,那么那个日期也有某种盛宴。

“只有”一件事使整个想法变得复杂......字段'year'可以为空。如果 'year' 为空,则表示当天有活动盛宴 - 与年份无关。(当然我可以为日期创建一个字段,以及一些布尔标志'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。

4

2 回答 2

0

您可以使用 WITH RECURSIVE 查询 -参考

尝试这个 -

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;
于 2013-05-21T13:22:12.047 回答
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;
于 2013-05-21T13:37:42.687 回答