Разделение даты по финансовому году - PullRequest
4 голосов
/ 30 января 2010

Учитывая С даты , До даты и Система финансового года , я хочу получить всю длительность разделения в пределах задано с и по датам на основе системы финансового года. Ниже поясняется с примерами:

Пример 1: Система финансового года: с апреля по март

с даты: январь-05-2008 На сегодняшний день: май-15-2008

На основе системы финансового года продолжительность должна быть разделена на:

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

Пример 2: Система финансового года: с апреля по март

С даты: 17 января 2008 г. На сегодняшний день: 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

Ответы [ 3 ]

1 голос
/ 30 января 2010

Я на самом деле предпочитаю решение Andomar (с добавлением процессов, которые автоматически заполняют таблицу Periods), но для удовольствия вот решение, которое не требует его.

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;
1 голос
/ 30 января 2010

Вы можете создать таблицу, содержащую начало и конец всех финансовых лет, например,

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 голосов
/ 22 ноября 2011
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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...