2014-08-28 285 views
0

之間的財務年度返回清單也許我正在克服這一點,但我有點難住。從日期範圍

我試圖按財政年度按月歸總數據,每個財政年度返回一行,每個月都有一列。

我可以輕鬆地每月返回一列,但是試圖返回財政年度,因爲行被證明是最困難的部分。

我的理論是,一旦我有選擇作爲行財政年度,我可以簡單地加入到這個金融年/月總結出了子查詢,給我1元1

麻煩的是本財政年度開始8月1日。查詢的日期範圍可以從1個財政年度到可能跨越5年的日期範圍。

舉例來說,如果我有時間範圍從01/08/2013-31/07/2014,我想財政年度爲返回:

2013/2014 

如果我有時間範圍從01/08/2012-31/07/2014,我想下面的返回財政年度:

2012/2013 
2013/2014 

如果我有時間範圍從01/01/2012-28/08/2014,我想希望以下退回財政年度:

2011/2012 
2012/2013 
2013/2014 
2014/2015 

這是我迄今爲止的工作,但它不能按預期工作。

DECLARE @DateFrom datetime, @DateTo datetime 
SET @DateFrom = '2011-08-01' 
set @DateTo = '2014-07-31' 


; with FinYr as 
     (
     select @DateFrom as AllDate, @DAteTo as EndDate, case when datepart(MONTH, @DateFrom) < 8 then convert(varchar(4),datepart(year, @DateFrom)-1)+'/'+convert(varchar(4),datepart(year, @DateFrom)) else convert(varchar(4),datepart(year, @DateFrom))+'/'+convert(varchar(4),datepart(year, @DateFrom)+1) End as FinYear 
     union all 
     select dateadd(year,1,AllDate) as AllDate, dateadd(year,1,EndDate) as EndDate,case when datepart(MONTH, dateadd(year,1,AllDate)) < 8 then convert(varchar(4),datepart(year, dateadd(year,1,AllDate))-1)+'/'+convert(varchar(4),datepart(year, dateadd(year,1,AllDate))) else convert(varchar(4),datepart(year, dateadd(year,1,AllDate)))+'/'+convert(varchar(4),datepart(year, dateadd(year,1,AllDate))+1) End as FinYear 
     from FinYr 
     where dateadd(year,-1,EndDate) <= convert(datetime,(convert(varchar(4),year(@Dateto))+'-07-31')) 
     ) 
select AllDate,EndDate, FinYear 
from FinYr 
+0

你能後的DDL和FinYr一些示例數據? – 2014-08-28 14:10:48

+0

FinYr不是來自dbase的數據,它是一個遞歸函數。 – OWSam 2014-08-28 14:14:15

+0

哦好悲傷....我需要更多的咖啡統計! – 2014-08-28 14:18:31

回答

1

您可以使用一個理貨或數字表來這樣的事情。在我的代碼中,我創建了Tally表。這是一個零讀取類型的實現...超快速。

DECLARE @DateFrom datetime, @DateTo datetime; 
SET @DateFrom = '2011-08-01'; 
set @DateTo = '2014-07-31'; 

WITH 
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)), 
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows 
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max 
    cteTally(N) AS 
    (
     SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4 
    ) 

select CAST(N as CHAR(4)) + '/' + CAST(N + 1 as CHAR(4)) 
from cteTally 
where N >= DATEPART(YEAR, @DateFrom) 
and N <= DATEPART(YEAR, @DateTo); 

確定更新的要求,只需稍微調整上述代碼即可完成此操作。這應該讓你在那裏。

select CAST(N as CHAR(4)) + '/' + CAST(N + 1 as CHAR(4)) 
from cteTally 
where N >= case when DATEPART(MONTH, @DateFrom) > 6 then DATEPART(YEAR, @DateFrom) else DATEPART(YEAR, DATEADD(YEAR, 1, @DateFrom)) end 
and N <= case when DATEPART(MONTH, @DateTo) < 6 then DATEPART(YEAR, @DateTo) else DATEPART(YEAR, DATEADD(YEAR, 1, @DateTo)) end 

我想我看到我在那裏做錯了....試試這個。

select CAST(N as CHAR(4)) + '/' + CAST(N + 1 as CHAR(4)) 
, case when DATEPART(MONTH, @DateTo) < 8 then DATEPART(YEAR, DATEADD(YEAR, -1, @DateTo)) else DATEPART(YEAR, DATEADD(YEAR, 1, @DateTo)) end 
from cteTally 
where N >= case when DATEPART(MONTH, @DateFrom) > 6 then DATEPART(YEAR, @DateFrom) else DATEPART(YEAR, DATEADD(YEAR, 1, @DateFrom)) end 
and N <= case when DATEPART(MONTH, @DateTo) < 8 then DATEPART(YEAR, DATEADD(YEAR, -1, @DateTo)) else DATEPART(YEAR, DATEADD(YEAR, 1, @DateTo)) end 
+0

它產生的正是你所說的你想要的輸出。什麼是不正確的呢?如果你讓我知道什麼是不正確的,我可以修復它。 – 2014-08-28 14:47:27

+0

嗯似乎很接近... 如果我把日期範圍 '2013-08-01' - '2014-08-20' 然後它返回2013/2014和2014/2015預期。 如果我把在: 「2013-08-01'-‘2014年7月30日’ 它仍然返回2013/2014和2014/2015凡在那種情況下,它只應該reuturn 2013/2014 – OWSam 2014-08-28 14:47:33

+0

爲什麼輸出變化? 7月1日您的財務年度有變化嗎?他們總是在7月1日改變?如果開關日期是可變的,那麼你應該使用日曆表。 – 2014-08-28 14:48:51

0

我相信,這將顯示出你想要的幾年名單:

DECLARE 
    @DateFrom datetime, 
    @DateTo datetime 
SET @DateFrom = '2011-01-01' 
SET @DateTo = '2014-07-31' 


SELECT CAST(YearList AS VARCHAR(4)) + '/' + CAST((YearList +1) AS VARCHAR(4)) AS FiscalYear 
FROM 
    (
    SELECT 
     DATEPART(YEAR, @DateFrom) - CASE WHEN DATEPART(MONTH, @DateFrom) >= 8 THEN 0 ELSE 1 END + 
     ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY (SELECT NULL)) -1 AS YearList 
    FROM sys.all_objects 
) q 
WHERE YearList <= DATEPART(YEAR, @DateTo) - CASE WHEN DATEPART(MONTH, @DateTo) >= 8 THEN 0 ELSE 1 END 
+0

感謝您的回答,但與其他答案一樣,我得到了太多的一年。截至2013年7月31日的選擇只應歸還2010/2011,2011/2012,2012/2013和2013/2014,因爲31/07/2014是2013/2014財政年度的最後一天。 我實際上得到2010/2011,2011/2012,2012/2013,2013/2014和2014/2015 – OWSam 2014-08-28 15:14:56

+0

我使用cte的原因是因爲它可以讓您對這些值進行一些控制。 sys.all_objects可能是一個很小的數字,它可能沒有足夠的行數。 – 2014-08-28 15:23:39

+0

對不起@OWSam,我的瀏覽器沒有彈出您的消息,我沒有及時收到它來處理它。無論它值什麼,我都編輯過。肖恩,我認爲CTE是同樣的事情,但考慮到OP中RDBMS規範的缺乏以及實際可回收的財政年數可能較少的情況,簡單起見就很簡單了。 – AHiggins 2014-08-28 16:07:34