2015-10-23 34 views
0

我有一个postgres表,存储称为appointments的定期约会。我也有一个名为day_of_week的枚举类型。postgres如何实现枚举数组中的每个值的行

day_of_week是一个枚举,看起来像:

select enum_range(null::ck_day_of_week); 

回报

{Monday,Tuesday,Thursday,Sunday,Saturday,Friday,Wednesday} 

的预约表的DDL为:

create table appointments 
(
    id serial primary key not null, 
    title varchar not null 
    recurrence_start_date timestampz not null, 
    recurrence_end_date timestampz, 
    recurrence_days_of_week _ck_day_of_week -- this is actually an array of enums, not just an enum. I don't fully understand why the DDL looks like this 
); 

select id, title, recurrence_days_of_week from appointments where recurrence_start_date <= now() and (recurrence_end_date is null or recurrence_end_date >= now()); 
查询

回报是这样的:

1,My Recurring Appointment,{Wednesday,Thursday,Friday,Saturday,Sunday} 

我的问题是,我需要“物化”了这个结果,我的UI视图的一组行。具体来说,我想查询数据库,并使其返回像行:

id,My Recurring Appointment,date 

其中唯一的密钥可能会在预约编号和具体date并在date是recurrence_start_date +星期几的基本组合(星期几是0到6之间的偏移量)。

在postgres中,如何从具有列的枚举数组的表中选择一个列,并让它返回一个--virtual--单行--real - 相同的行,对于每个枚举值阵列?我正在考虑一个视图或其他东西,但我现在确定如何编写select语句。

奖励积分,如果这可以被翻译成SQLAlchemy的....

我也开,并认为只是创造,存储,其具体日期每个约会的约会表。但是,如果我这样做......理论上,对于没有结束日期的重复日期的约会,表格可能无限大,所以我一直在试图避免这种情况。

回答

0

首先,我不建议使用id作为有史以来的列名。其次,我会使用内置的日期/时间函数来实现第一个目标。更具体地说,组合extract函数与dow参数(星期几)和generate_series函数与。

请务必检查小提琴参考文献部分。

查询一周的每一天回来的appointments名单:一周的预约天

create or replace function fnc_appointment_list_dow_by_id(_app_id int) 
    returns table (__app_id int, __title varchar, __recurrence_start_date timestamptz, __recurrence_appointment_day timestamptz, __reccurence_dow_offset int) as 
$body$ 
     select 
       app.app_id, 
       app.app_title, 
       app.app_recurrence_start_date, 
       _appointment_days._day, 
       extract(dow from _day)::int 
      from 
       appointments app, 
       generate_series(app.app_recurrence_start_date, app.app_recurrence_end_date, interval '1 day') _appointment_days(_day) 
      where app.app_id=_app_id; 
$body$ 
    language sql stable; -- consider changing function volatility as needed. 

-- select * from fnc_appointment_list_dow_by_id(1); 

查询返回数组:

create or replace function fnc_appointment_array_dow_by_id(_app_id int) 
     returns table (__app_id int, __title varchar, __recurrence_start_date timestamptz, __recurrence_appointment_day timestamptz[], __reccurence_dow_offset int[]) as 
    $body$ 
     select 
       app.app_id, 
       app.app_title, 
       app.app_recurrence_start_date, 
       array_agg(_day::timestamptz), 
       array_agg(extract(dow from _day)::int) 
      from 
       appointments app, 
       generate_series(app.app_recurrence_start_date, app.app_recurrence_end_date, interval '1 day') as _appointment_days(_day) 
      where app.app_id=_app_id 
      group by app.app_id, app.app_title, app.app_recurrence_start_date; 
    $body$ 
     language sql stable; -- consider changing function volatility as needed. 

-- select * from fnc_appointment_array_dow_by_id(1); 

如果任何一个功能是你在找什么让我知道,我们可以继续下一个目标。

参考

+0

非常感谢这么有帮助的回复。这实际上让我到了我所需要的地方 - 我想 - 它有点儿挡住了我所拥有的数组枚举列。我需要的第一件事是每周的活动{周一,周二,周四,周日,周六,周五,周三}。一旦我有了,我就能够使用你提到的概念,比如extract和generate_series来产生重现。 – lostdorje

+0

很高兴你知道了。干杯。 – Nick