2010-01-30 72 views
4

給出一個起始日期迄今爲止財政年度系統,我想根據從&給出迄今爲止 內的所有分裂的持續時間來獲得財政年度系統。解釋下面的例子:日期分裂

例1: 財政年度系統:4至3月

開始日期:一月-05-2008 要日期:5月15-2008基於財政

年系統,持續時間應該分裂成:

Jan-05-2008 to Mar-31-2008 
Apr-01-2008 to May-15-2008 

實施例2: 財政年度小號ystem:4至3月

開始日期:一月-17-2008 要日期:5月20-2009

基於財年的系統上,持續時間應該分裂成:

Jan-17-2008 to Mar-31-2008 
Apr-01-2008 to Mar-31-2009 
Apr-01-2009 to May-20-2009 

上午尋找在PostgreSQL 8.2中解決這個問題的方法/算法。

問候,

Gnanam

回答

1

其實我贊成Andomar的解決方案(加入了自動填充週期表中的過程),但爲了好玩這裏不需要它的解決方案。

CREATE TABLE your_table (start_date date, end_date date); 
INSERT INTO your_table VALUES ('Jan-17-2008', 'May-20-2009'); 

SELECT 
    GREATEST(start_date, ('04-01-'||series.year)::date) AS year_start, 
    LEAST(end_date, ('03-31-'||series.year + 1)::date) AS year_end 
FROM 
    (SELECT 
     start_date, 
     end_date, 
     generate_series(
      date_part('year', your_table.start_date - INTERVAL '3 months')::int, 
      date_part('year', your_table.end_date - INTERVAL '3 months')::int) 
    FROM your_table) AS series(start_date, end_date, year) 
ORDER BY 
    start_date; 
+0

嗨cope360, 這真的很棒,它以簡單的方式解決了我的問題。 再次感謝您。 – Gnanam 2010-02-01 05:33:14

1

你可以創建一個包含所有財年的開始和結束的表,F.E.

Periods (PeriodStartDt, PeriodEndDt) 

然後你可以join表一起,如果他們至少部分重疊。使用case語句來選擇時間段的結尾或行的結尾,具體取決於後面的內容。例如(未測試):

select  case when yt.StartDt < p.PeriodStartDt then p.PeriodStartDt 
       else yt.StartDt 
      end as SplitStart 
,   case when yt.EndDt > p.PeriodEndDt then p.PeriodEndDt 
       else yt.EndDt 
      end as SplitEnd 
,   yt.* 
from  YourTable yt 
inner join Periods p 
on   yt.StartDt < p.PeriodEndDate 
      and yt.EndDt >= p.PeriodStartDate 
+0

讓我什麼我究竟需要添加一些額外的投入。 MYTABLE(FROMDATE,TODATE) 從日期和日期檢索數據庫表。拆分持續時間必須在plpgsql中以編程方式找到 ,並且不與記錄匹配。 – Gnanam 2010-01-30 13:27:43

0
CREATE TABLE your_table (start_date date, end_date date); 
INSERT INTO your_table VALUES (CONVERT (date, GETDATE()),CONVERT (date, DATEADD(year, -1, GETDATE()))); 

WITH mycte AS 
(
SELECT 1 as id 
UNION ALL 
SELECT id + 1 
FROM mycte 
WHERE id + 1 < = 12 
), 
cte_distribution as 
(
SELECT *, 
DATEPART (month,DATEADD(month, mycte.id - 1, your_table.start_date)) as month_number , 
DATEPART (YEAR,DATEADD(month, mycte.id - 1, your_table.start_date)) as cal_year, 
12000/12 as cash 
FROM your_table 
CROSS JOIN mycte 
) 
select 
*, 
(CASE WHEN month_number between 1 and 3 THEN '1st quarter' WHEN month_number between 4 and 6 THEN '2nd quarter' WHEN month_number between 7 and 9 THEN '3rd quarter' WHEN month_number between 9 and 12 THEN '4th quarter' END) as Quarter, 
CASE WHEN month_number between 1 and 6 THEN CAST(CAST((cal_year - 1) as CHAR(4)) + '-' + CAST(cal_year as CHAR(4)) AS CHAR(9)) WHEN month_number between 6 and 12 THEN CAST(CAST((cal_year) as CHAR(4)) + '-' + CAST((cal_year + 1) as CHAR(4)) AS CHAR(9)) ELSE NULL END as fin_year 
from cte_distribution;