SQL查询返回会计年度和季度

时间:2018-06-28 17:54:07

标签: sql sql-server date sql-server-2016

有一个表格,列出了每个四个季度以及它们的开始/结束日期和月份。

鉴于此表以及2017年的开始年份,我如何获得(结束)日期和名称格式的季度列表,例如2017年第三季度的'06 / 30/2017'?

我尝试过,但是只能得到当前季度:

select q.QID, q.QuarterName, q.StartMonth, q.StartDay, q.EndMonth, q.EndDay,
datefromparts(datepart (yy, '1/1/2017'), q.StartMonth, q.StartDay) StartQuarter, 
datefromparts(datepart (yy, '6/28/2018'), q.EndMonth, q.EndDay) EndQuarter 
from Quarters q 
where datefromparts(datepart (yy, '6/28/2018'), q.EndMonth, q.EndDay) < '06/30/2018';

“季度”表如下:

QID QuarterName     StartMonth  StartDay    EndMonth    EndDay
1   First Quarter   10          1           12          31
2   Second Quarter  1           1           3           31
3   Third Quarter   4           1           6           30
4   Fourth Quarter  7           1           9           30

不确定这是否相关,但已在.Net / C#环境中使用。

3 个答案:

答案 0 :(得分:0)

这似乎是您想要的。您可以使用递归CTE并忽略此表来执行此操作多年...

declare @quarters table (QID int, QuarterName varchar(64), StartMonth int,  StartDay int,  EndMonth int,    EndDay int)
insert into @quarters
values

(1,'First Quarter',10,1,12,31),
(2,'Second Quarter',1,1,3,31),
(3,'Third Quarter',4,1,6,30),
(4,'Fourth Quarter',7,1,9,30)


declare @year int = '2018'

select
    *
    ,convert(varchar,convert(date,cast(@year as varchar) + right('0' + cast(EndMonth as varchar),2)  + cast(EndDay as varchar)),101) 
from @quarters

或者,递归CTE ...

;with cte as(
    select 
        *
        ,EndDate = convert(date,convert(date,cast(datepart(year,@startDate) as varchar) + right('0' + cast(EndMonth as varchar),2)  + cast(EndDay as varchar)))
    from @quarters
    union all
    select
        Qid
        ,QuarterName
        ,StartMonth
        ,StartDay
        ,EndMonth
        ,EndDay
        ,dateadd(year,1,EndDate)
    from cte
    where datepart(year,EndDate) <= datepart(year,@endDate)
    )

select
        Qid
        ,QuarterName
        ,StartMonth
        ,StartDay
        ,EndMonth
        ,EndDay
        ,EndDate = convert(varchar,EndDate,101)
from cte

答案 1 :(得分:0)

由于您的会计年度转移了一个QTR,也许另一个选择使用CHOOSE

示例

Declare @Date1 date = '2017-10-01'

Select DateR1 = D
      ,DateR2 = EOMONTH(D)
      ,AsString = concat(choose(DatePart(QQ,D),'Q2','Q3','Q4','Q1'),' ',year(D)-IIF(DatePart(QQ,D)<4,1,0) )
      ,AsDate   = format(EOMonth(D),'MM/dd/yyyy')
From (
        Select Top (12) D=DateAdd(MONTH,-1+Row_Number() Over (Order By (Select Null)),@Date1) From  master..spt_values n1,master..spt_values n2
     ) A

返回

DateR1      DateR2      AsString    AsDate
2017-10-01  2017-10-31  Q1 2017     10/31/2017
2017-11-01  2017-11-30  Q1 2017     11/30/2017
2017-12-01  2017-12-31  Q1 2017     12/31/2017
2018-01-01  2018-01-31  Q2 2017     01/31/2018
2018-02-01  2018-02-28  Q2 2017     02/28/2018
2018-03-01  2018-03-31  Q2 2017     03/31/2018
2018-04-01  2018-04-30  Q3 2017     04/30/2018
2018-05-01  2018-05-31  Q3 2017     05/31/2018
2018-06-01  2018-06-30  Q3 2017     06/30/2018
2018-07-01  2018-07-31  Q4 2017     07/31/2018
2018-08-01  2018-08-31  Q4 2017     08/31/2018
2018-09-01  2018-09-30  Q4 2017     09/30/2018

答案 2 :(得分:0)

尝试一下:

DECLARE @year INT = 2017;

WITH numbers(n) AS (
  SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1
  FROM       (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS v1(x)
  CROSS JOIN (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS v2(x)
)
SELECT CONCAT('Q', QID, ' ', @year + n) AS QuarterName, EndDate
FROM numbers
CROSS JOIN Quarters
CROSS APPLY (SELECT
  DATEFROMPARTS(@year + n - CASE WHEN QID = 1 THEN 1 ELSE 0 END, StartMonth, StartDay) AS StartDate,
  DATEFROMPARTS(@year + n - CASE WHEN QID = 1 THEN 1 ELSE 0 END, EndMonth, EndDay) AS EndDate
) AS CA
WHERE StartDate <= CURRENT_TIMESTAMP ORDER BY EndDate

numbers公用表表达式生成介于0和99之间的数字(see this question)。这些交叉乘以Quarters表。通过将@year添加到每个数字来生成日期,并由于n属于第一季度n - 1 年的第一季度而进行了调整。交叉应用可以更轻松地引用WHERESELECTORDER BY子句中的计算值。

结果:

| QuarterName | EndDate    |
|-------------|------------|
| Q1 2017     | 2016-12-31 |
| Q2 2017     | 2017-03-31 |
| Q3 2017     | 2017-06-30 |
| Q4 2017     | 2017-09-30 |
| Q1 2018     | 2017-12-31 |
| Q2 2018     | 2018-03-31 |
| Q3 2018     | 2018-06-30 |

SQL Fiddle稍加修改