微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

获取超过一年的季度开始/结束日期开始年份到当年

如何解决获取超过一年的季度开始/结束日期开始年份到当年

我一直试图在给定特定日期/年份的情况下获取每个季度的开始和结束日期范围,如下所示:

 SELECT DATEADD(mm,(quarter - 1) * 3,year_date) StartDate,DATEADD(dd,DATEADD(mm,quarter * 3,year_date)) EndDate
       --quarter QuarterNo
  FROM
(
  SELECT '2012-01-01' year_date
) s CROSS JOIN 
(
  SELECT 1 quarter UNION ALL
  SELECT 2 UNION ALL
  SELECT 3 UNION ALL
  SELECT 4
) q

产生以下输出

2012-01-01 00:00:00 2012-04-01 00:00:00
2012-04-01 00:00:00 2012-07-01 00:00:00
2012-07-01 00:00:00 2012-10-01 00:00:00
2012-10-01 00:00:00 2013-01-01 00:00:00

问题:我需要针对给定的 start_dateend_date 执行此操作,问题是 end_date=current_day,那么我该如何实现:

2012-01-01 00:00:00 2012-04-01 00:00:00
2012-04-01 00:00:00 2012-07-01 00:00:00
2012-07-01 00:00:00 2012-10-01 00:00:00
2012-10-01 00:00:00 2013-01-01 00:00:00
    ...   ...
2021-01-01 00:00:00   2021-01-06 00:00:00

解决方法

我认为这就是您想要做的:

SET startdatevar AS DATEtime = '2020-01-10' 
;WITH RECURSIVE cte AS (

SELECT startdatevar AS startdate,DATEADD(QUARTER,1,startdatevar) enddate,1 quarter
UNION ALL 
SELECT enddate,CASE WHEN DATEADD(QUARTER,enddate) > CURRENT_DATE() THEN GETDATE() ELSE DATEADD(QUARTER,enddate) END enddate,quarter + 1
FROM cte 
WHERE 
    cte.enddate <= CURRENT_DATE()
     and quarter < 4
)


SELECT * FROM cte

使用你的代码,如果你想要超过 4 个季度:

SET quarter_limit = DATEDIFF(quarter,<startdate>,<enddate>)
;WITH RECURSIVE cte(q,qDate,enddate) as
    (
        select 1,DATEFROMPARTS(year('2012-01-01'::date),1) -- First quarter date,time_slice('2012-01-01'::date,3,'MONTH','END')
         UNION ALL
         select q+1,DATEADD(q,qdate) -- next quarter start date,time_slice(qdate::date,(q+1)*3,'END')
         from cte
         where q < quarter_limit -- limiting the number of next quarters
         AND cte.endDate <= <enddate>
     )
     SELECT * FROM cte
,

@eshirvana 的回答之后,我在您的回答之后想出了这个稍微的变化:

WITH RECURSIVE cte(q,'END')
         from cte
         where q <4 -- limiting the number of next quarters
         AND cte.endDate <= CURRENT_DATE() 
     )
     SELECT * FROM cte

无论我经过那里的哪一年都可以正常工作(2012 年将产生 4 个记录,2021 年只有一个,因为我们现在仍处于第一季度)。

[编辑]:在您的第二个代码sugestion 之后它仍然不能按预期工作:

 WITH RECURSIVE cte(q,CASE  WHEN time_slice('2012-01-01'::date,'END') > CURRENT_DATE
            THEN current_date 
            ELSE time_slice('2012-01-01'::date,'END') 
            END
         UNION ALL
         select q+1,'END')
         from cte
         where q < DATEDIFF(quarter,'2012-01-01'::date,'2021-01-06'::date)
         AND cte.endDate <= '2021-01-06'::date
     )
     SELECT * FROM cte 

正在输出: 抱歉@eshirvana,但它没有按预期工作。在某种程度上一切顺利,但它并没有返回所有记录。相反,它产生较少的记录和错误的记录,如下所示:

1   2012-01-01  2012-04-01
2   2012-04-01  2012-07-01
3   2012-07-01  2012-10-01
4   2012-10-01  2013-01-01
5   2013-01-01  2013-10-01
6   2013-04-01  2013-07-01
7   2013-07-01  2013-10-01
8   2013-10-01  2014-01-01
9   2014-01-01  2015-01-01
10  2014-04-01  2015-01-01
11  2014-07-01  2016-10-01
12  2014-10-01  2015-01-01
13  2015-01-01  2015-07-01
14  2015-04-01  2015-07-01
15  2015-07-01  2018-10-01
16  2015-10-01  2018-01-01
17  2016-01-01  2016-10-01
18  2016-04-01  2019-07-01
19  2016-07-01  2017-07-01
20  2016-10-01  2020-01-01
21  2017-01-01  2017-04-01
22  2017-04-01  2019-07-01
23  2017-07-01  2021-10-01

虽然我的逻辑是不只打印 2021 年第一季度的日期还是不行,这个输出问题可能与日期格式或其他什么有关吗?

,

现在,它似乎有效,至少从 2012-01-01 到今天(2021-01-06)。

代码:

 WITH RECURSIVE cte(q,enddate) as
    (
        select 
        -- it might not be the first quarter,so better to protect that:
         quarter('2012-01-01'::date)::numeric,CASE WHEN time_slice('2012-01-01'::date,'END') > '2021-01-06'::date
            THEN '2021-01-06'::date
            ELSE time_slice('2012-01-01'::date,CASE  WHEN time_slice(DATEADD(q,qdate),'END')> '2021-01-06'::date
            THEN '2021-01-06'::date
            ELSE time_slice(DATEADD(q,'END')
            END
         from cte
         where q <= DATEDIFF(quarter,'2021-01-06'::date)
         AND cte.endDate <= '2021-01-06'::date
     )
     SELECT * FROM cte  

输出:

1   2012-01-01  2012-04-01
2   2012-04-01  2012-07-01
3   2012-07-01  2012-10-01
4   2012-10-01  2013-01-01
5   2013-01-01  2013-04-01
6   2013-04-01  2013-07-01
7   2013-07-01  2013-10-01
8   2013-10-01  2014-01-01
9   2014-01-01  2014-04-01
10  2014-04-01  2014-07-01
11  2014-07-01  2014-10-01
12  2014-10-01  2015-01-01
13  2015-01-01  2015-04-01
14  2015-04-01  2015-07-01
15  2015-07-01  2015-10-01
16  2015-10-01  2016-01-01
17  2016-01-01  2016-04-01
18  2016-04-01  2016-07-01
19  2016-07-01  2016-10-01
20  2016-10-01  2017-01-01
21  2017-01-01  2017-04-01
22  2017-04-01  2017-07-01
23  2017-07-01  2017-10-01
24  2017-10-01  2018-01-01
25  2018-01-01  2018-04-01
26  2018-04-01  2018-07-01
27  2018-07-01  2018-10-01
28  2018-10-01  2019-01-01
29  2019-01-01  2019-04-01
30  2019-04-01  2019-07-01
31  2019-07-01  2019-10-01
32  2019-10-01  2020-01-01
33  2020-01-01  2020-04-01
34  2020-04-01  2020-07-01
35  2020-07-01  2020-10-01
36  2020-10-01  2021-01-01
37  2021-01-01  2021-01-06

如果您想知道:是的,我们的想法是将 end_date 显示为月份的最后一天 + 一。但它很容易适应。

它并不漂亮,但我认为它很容易理解。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。