如何解决获取超过一年的季度开始/结束日期开始年份到当年
我一直试图在给定特定日期/年份的情况下获取每个季度的开始和结束日期范围,如下所示:
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_date 和 end_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 举报,一经查实,本站将立刻删除。