Showing what quarter of a financial year a date is in

a 夏天 提交于 2019-12-04 23:49:49

问题


I'm trying to construct a query that will map two columns, one, a date from a table, the second column an alias to show what quarter and financial year the date falls into.

Unfortunately I don't have enough knowledge of SQL to know where to begin. I know that I'd do this with a combination of getdate() and dateadd(MONTH,,) however nothing that I've put together has come close to working.

To further complicate this the financial years in Australia go from 1st July- 30th of June so quarter one of financial year 2012 would start from July 1st 2012.

I can do this without a statement however I'd much rather have it in a statement as it's going to be used in an SSRS report and a C# application and it would make maintenance significantly easier.


回答1:


This should work:-

SELECT
    MyDate,
    CASE
        WHEN MONTH(MyDate) BETWEEN 1  AND 3  THEN convert(char(4), YEAR(MyDate) - 1) + 'Q3'
        WHEN MONTH(MyDate) BETWEEN 4  AND 6  THEN convert(char(4), YEAR(MyDate) - 1) + 'Q4'
        WHEN MONTH(MyDate) BETWEEN 7  AND 9  THEN convert(char(4), YEAR(MyDate) - 0) + 'Q1'
        WHEN MONTH(MyDate) BETWEEN 10 AND 12 THEN convert(char(4), YEAR(MyDate) - 0) + 'Q2'
    END AS Quarter
FROM
    MyTable

Output:-

MyDate        Quarter
----------    --------
2011-01-01    "2010Q3"
2011-04-01    "2010Q4"
2011-07-01    "2011Q1"
2011-10-01    "2011Q2"



回答2:


This method doesn't require a CASE statement, and works for any monthly fiscal calendar.

DECLARE @firstMonthOfFiscalQ1 int = 7; --1=January
SELECT DateColumn
    , FLOOR(((12 + MONTH(DateColumn) - @firstMonthOfFiscalQ1) % 12) / 3 ) + 1 AS FiscalQuarter
    FROM SomeTable 
    WHERE 1=1;



回答3:


I think it would be easiest to do this with CASE

SELECT
   date
   , CASE
         WHEN MONTH(date) BETWEEN 7 AND 9 THEN 'First Quarter'
         WHEN MONTH(date) BETWEEN 10 AND 12 THEN 'Second Quarter'
         WHEN MONTH(date) BETWEEN 1 AND 3 THEN 'Third Quarter'
         WHEN MONTH(date) BETWEEN 4 AND 6 THEN 'Fourth Quarter'
     END AS quarter
FROM Stuff



回答4:


Just in case you want to do some wacky mathematical operations to avoid a case statement:

select mydate,
   convert(char(4), year(mydate) - (((DATEPART(qq, mydate) - ((DATEPART(qq, mydate) + 1) % 4) + 1) / -4) + 1)) + 
   'Q' + convert(char(1), ((DATEPART(qq, mydate) + 1) % 4) + 1) quar
from sampleData



回答5:


Consider creating an equivalent of a Date Dimension table from a data warehouse. This would have one row per day for every year your data could possibly cover (start from some reasonable epoch and go forward until some reasonably far future date).

Within this table, you would have columns describing info about every day - including calendar year, half-year, quarter, month; and fiscal year, half-year, quarter.

Your report then simply joins to this table based on date to pull this info. This gives you future support for other info about dates also, and removes the responsibility of this calculation from each individual reporting query.




回答6:


I found that using 'Explosion Pills' result worked, but I wanted mine to look like the answer by 'Adam Ralph', however I kept experiencing errors. I was able to work around this and created a new CASE example:

    CASE    -- Results:  2011 (Financial Year )
            WHEN MONTH(MyDate) BETWEEN 1  AND 3  THEN (YEAR(MyDate) - 1)
            WHEN MONTH(MyDate) BETWEEN 4  AND 6  THEN (year(MyDate) - 1)
            WHEN MONTH(MyDate) BETWEEN 7  AND 9  THEN (YEAR(MyDate) - 0)
            WHEN MONTH(MyDate) BETWEEN 10 AND 12 THEN (YEAR(MyDate) - 0)
    END AS FYr,

    CASE    -- Results:  Q4 (Financial Qtr)
            WHEN MONTH(MyDate) BETWEEN 7 AND 9 THEN 'Q1'
            WHEN MONTH(MyDate) BETWEEN 10 AND 12 THEN 'Q2'
            WHEN MONTH(MyDate) BETWEEN 1 AND 3 THEN 'Q3'
            WHEN MONTH(MyDate) BETWEEN 4 AND 6 THEN 'Q4'
    END AS FQtr,

            -- https://stackoverflow.com/a/22170892/2337102
    CASE    -- Results:  2011-Q4  (Financial Yr-Qtr)
            WHEN MONTH(MyDate) BETWEEN 1  AND 3  THEN concat((YEAR(MyDate) - 1), '-', 'Q3')
            WHEN MONTH(MyDate) BETWEEN 4  AND 6  THEN concat((YEAR(MyDate) - 1), '-', 'Q4')
            WHEN MONTH(MyDate) BETWEEN 7  AND 9  THEN concat((YEAR(MyDate) - 0), '-', 'Q1')
            WHEN MONTH(MyDate) BETWEEN 10 AND 12 THEN concat((YEAR(MyDate) - 0), '-', 'Q2')
    END AS FYrQtr,


    CASE    --  Results:  11-Q4   (Financial (short) Yr-Qtr)
            WHEN MONTH(MyDate) BETWEEN 1  AND 3  THEN concat((date_format(MyDate, '%y') - 1), '-', 'Q3')
            WHEN MONTH(MyDate) BETWEEN 4  AND 6  THEN concat((date_format(MyDate, '%y') - 1), '-', 'Q4')
            WHEN MONTH(MyDate) BETWEEN 7  AND 9  THEN concat((date_format(MyDate, '%y') - 0), '-', 'Q1')
            WHEN MONTH(MyDate) BETWEEN 10  AND 12  THEN concat((date_format(MyDate, '%y') - 0), '-', 'Q2')
    END AS FYrQtr,

    CASE    --  Results:  2011-2012/Q4  (Financial Range Yr/Qtr)
            WHEN MONTH(MyDate) BETWEEN 1  AND 3  THEN concat(YEAR(MyDate) - 1,'-', YEAR(MyDate), '/', 'Q3')
            WHEN MONTH(MyDate) BETWEEN 4  AND 6  THEN concat(YEAR(MyDate) - 1,'-', YEAR(MyDate),  '/', 'Q4')
            WHEN MONTH(MyDate) BETWEEN 7  AND 9  THEN concat(YEAR(MyDate) - 0,'-', YEAR(MyDate) + 1,  '/', 'Q1')
            WHEN MONTH(MyDate) BETWEEN 10  AND 12  THEN concat(YEAR(MyDate) - 0,'-', YEAR(MyDate) + 1,  '/', 'Q2')
    END AS FRangeQtr,

    CASE    --  Results:  11-12/Q4  (Financial Range (short) Yr/Qtr)
            WHEN MONTH(MyDate) BETWEEN 1  AND 3  THEN concat((date_format(MyDate, '%y') - 1),'-', (date_format(MyDate, '%y')), '/', 'Q3')
            WHEN MONTH(MyDate) BETWEEN 4  AND 6  THEN concat((date_format(MyDate, '%y') - 1),'-', (date_format(MyDate, '%y')), '/', 'Q4')
            WHEN MONTH(MyDate) BETWEEN 7  AND 9  THEN concat((date_format(MyDate, '%y') - 0),'-', (date_format(MyDate, '%y') + 1), '/', 'Q1')
            WHEN MONTH(MyDate) BETWEEN 10  AND 12  THEN concat((date_format(MyDate, '%y') - 0),'-', (date_format(MyDate, '%y') + 1), '/', 'Q2')
    END AS FRangeQtr2,

I am adding my answer hoping it will help someone else who comes via Google and experiences issues.




回答7:


A few years late to the game, but here's my quick-easy-clean method for Australians using GetDate(). Even your accounting calendar is upside-down :)

SELECT CHOOSE(MONTH(GetDate()),'3Q','3Q','3Q','4Q','4Q','4Q','1Q','1Q','1Q','2Q','2Q','2Q') AS AccountingQuarter

The SQL choose command takes the month of the date as the parameter, then chooses from the 12 available options. Of course, most other systems would start with 1Q/Q1 in the first choice.




回答8:


Maybe I don't understand the question but the accepted answer does not seem correct. Financial quarter depends on which month the financial year starts, so it will always (?) be a calculation with 2 dates.

Here's what worked for me, no case statement:

CEILING((DATEDIFF(MONTH, FinYearStartDate, MonthStartDate)) / 3) + 1



回答9:


SELECT
MyDate,
CASE
    WHEN MONTH(MyDate) IN (1,2,3)  THEN convert(char(4), YEAR(MyDate) - 1) + 'Q3'
    WHEN MONTH(MyDate) IN (4,5,6)  THEN convert(char(4), YEAR(MyDate) - 1) + 'Q4'
    WHEN MONTH(MyDate) IN (7,8,9)  THEN convert(char(4), YEAR(MyDate) - 0) + 'Q1'
    WHEN MONTH(MyDate) IN (10,11,12) THEN convert(char(4), YEAR(MyDate) - 0) + 'Q2'
END AS Quarter  FROM MyTable

The above answers do not consider the final month of the quarter

eg. between 1 and 3 will only return months 1 and 2...




回答10:


SELECT Opendate,Month(Opendate),
       (CASE WHEN (Month(Opendate)/6.0)<=1 THEN 1 ELSE 2 END) HALF_YEAR 
FROM TableName where Opendate <> '1900-01-01 00:00:00.000'



回答11:


Here's an alternative to the accepted answer:

declare @tbl table (MyDate datetime)
insert into @tbl values ('2011-01-01')
insert into @tbl values ('2011-04-01')
insert into @tbl values ('2011-07-01')
insert into @tbl values ('2011-10-01')

SELECT CAST(MyDate AS DATE) as MyDate, CAST(YEAR(DATEADD(MONTH, -6, MyDate)) AS VARCHAR(4)) + 'Q'
    + CAST(DATEPART(q,DATEADD(MONTH, -6, MyDate)) AS VARCHAR(1)) AS Quarter
FROM @tbl

Output:

MyDate     Quarter
---------- -------
2011-01-01 2010Q3
2011-04-01 2010Q4
2011-07-01 2011Q1
2011-10-01 2011Q2

This works even if MyDate is something like August 31 - if you subtract 6 months from 8/31 in SQL, you get 2/28 (although 2/31 doesn't exist, MSSQL still knows you probably want the last day of the month). Since the quarter is based on the month of the year, this approach works.




回答12:


This code converts date to year and month, which is beginning of a quarter.

DATEADD(quarter, DATEDIFF(quarter, 0, @date), 0) year_and_first_month_of_quarter

So the months will be always:
YYYY-01-01
YYYY-04-01
YYYY-07-01
YYYY-10-01
Good thing about it - result is in datetime format.




回答13:


declare @sdate date='2017-12-01'
declare @edate date='2018-07-01'



;with rs as
(
   select   1 [QNum],@sdate StDT
   union all 
   select [QNum]+1, DATEADD(qq,1,stdt)   from rs where [QNum]<=datediff(qq,@sdate,@edate)
)
select QNum, convert(varchar(10),StDT,105) StDT,convert(varchar(10),dateAdd(m,3,DATEADD(d, -1, DATEADD(qq,DATEDIFF(qq, 0, stdt) + 1, 0))),105)EndDT from rs

--select left(datename(mm,s),3) + ' ' +cast(year(s) as varchar) from rs



回答14:


We already have a sysDate table that contains dates from Jan 1, 1900 to Dec 31, 2030 that we use for processing. We were asked to do fiscal year handling, and so we modified our table to include FiscalYearString varchar(9), FiscalYear int and FiscalQuarter int columns.

The script we use to update these columns is this:

DECLARE @StartingMonthOfFiscalYear INT = 4 -- 1-Jan, 2-Feb, 3-Mar, 4-Apr, 5-May, 6-Jun, 7-Jul, 8-Aug, 9-Sep, 10-Oct, 11-Nov, 12-Dec

UPDATE sysDate
SET FiscalYear = CASE WHEN MONTH([Date]) < @StartingMonthOfFiscalYear 
                        THEN YEAR([Date])-1 
                        ELSE YEAR([Date]) END,
    FiscalYearString = CASE WHEN MONTH([Date]) < @StartingMonthOfFiscalYear 
                        THEN CAST(YEAR([Date])-1 AS Varchar(4))+'/'+CAST(YEAR([Date]) AS Varchar(4)) 
                        ELSE CAST(YEAR([Date]) AS Varchar(4))+'/'+CAST(YEAR([Date])+1 AS Varchar(4)) END,
    FiscalQuarter = CASE WHEN MONTH([Date]) < @StartingMonthOfFiscalYear 
                        THEN ((MONTH([Date]) + 12 - @StartingMonthOfFiscalYear) / 3) + 1 
                        ELSE ((MONTH([Date]) - @StartingMonthOfFiscalYear) / 3) + 1 END

This updates over 47,000 rows in less than 1 second, saving us from having to recalculate every time we need it.




回答15:


I went looking for an answer today and decided that I should post my solution as it avoids a CASE statement:

select DATEPART(Quarter,dateadd(m,6,YourDate))/* add six months to move to FY */ qq

This is written for the Australian Financial year which is six months adjusted, you can see what I'm doing from this.




回答16:


it may helps someone

declare @dt uddt
select @dt=getdate()


select  case when month(@dt) between 1 and 3 then 'Q4' 
when month(@dt) between 4 and 6 then 'Q1'
when month(@dt) between 6 and 9 then 'Q2'
when month(@dt) between 9 and 12 then'Q3'
end as [Quarter] ,DATEADD(quarter, DATEDIFF(quarter, 0, @dt), 0) 
year_and_first_date_of_quarter,
DATEADD(d, -1, DATEADD(q,DATEDIFF(q, 0, @dt) + 1, 0)) 
year_and_last_date_of_quarter


来源:https://stackoverflow.com/questions/8738818/showing-what-quarter-of-a-financial-year-a-date-is-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!