2014-07-08 75 views
0

我有一個帶有時間戳字段的表格。在Postgresql中,我必須定義一個'營業月'作爲當月的第一個星期日到次月的第一個星期六(例如,2014年4月6日至2014年5月3日將是'2014年4月' )。定義一個營業月份:一個月的第一個星期日,直到下個月的第一個星期六

我不太確定從哪裏開始。到目前爲止,我從this forum post(使用T-SQL)獲得第一個星期天。

--first sunday of this month.... 
-1=sunday,-2=saturday,-3-friday etc 
SELECT 
datename(dw,dateadd(dd,-1,DATEADD(wk, 
DATEDIFF(wk,0,dateadd(dd,7-datepart(day,getdate()),getdate())), 0))), 
dateadd(dd,-1,DATEADD(wk, 
DATEDIFF(wk,0,dateadd(dd,7-datepart(day,getdate()),getdate())), 0)) 

我可能需要建立一個日曆表並手動定義月份。但我想探索其他解決方案。

+0

沒有其他的解決方案會比萬年曆錶更好。 –

+0

我會非常強烈地推薦一個日曆表。當你開始處理複雜的日期操作時,很容易搞砸你的邏輯,直到你投入生產之後的幾個月(甚至幾年)纔會注意到它。閏年是一個特別常見的錯誤來源。如果是我,我肯定會爲此創建一個日曆表。這比使用邏輯表達式處理日期要簡單得多。 – evanv

回答

0

SQL Fiddle

功能

create or replace function business_month("month" date) 
returns table (first_day date, last_day date) as $$ 

    with first_month_day as (
     select date_trunc('month', month)::date as first_day 
    ), first_business_day as (
     select 
      first_day 
      + (extract(dow from first_day)::int > 0)::int * 7 
      - extract(dow from first_day)::int 
      as first_day 
     from first_month_day 
    ), first_next_month_day as (
     select (first_day + interval '1 month')::date as first_day 
     from first_month_day 
    ), last_business_day as (
     select 
      first_day 
      + 6 
      - extract(dow from first_day)::int 
      as last_day 
     from first_next_month_day 
    ) 
    select 
     (select first_day from first_business_day) as first_day, 
     (select last_day from last_business_day) as last_day 
    ; 
$$ language sql stable; 

測試它

select 
    to_char(d, 'YYYY Month') as month, 
    to_char(first_day, 'YYYY-MM-DD Day') as first_day, 
    to_char(last_day, 'YYYY-MM-DD Day') as last_day 
from 
    generate_series ('2010-01-01'::date, '2014-12-31', '1 month') g (d) 
    , 
    business_month(d::date) 
; 
相關問題