2015-10-23 85 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