SQL 列出一年中每个季度的开始日期和结束日期

SQL 列出一年中每个季度的开始日期和结束日期,对于给定年份的四个季度,分别列出它们的开始日期和结束日期。

SQL 列出一年中每个季度的开始日期和结束日期 问题描述

对于给定年份的四个季度,分别列出它们的开始日期和结束日期。

SQL 列出一年中每个季度的开始日期和结束日期 解决方案

一年有四个季度,因此需要生成 4 行记录。在生成了足够多的行之后,直接调用各个关系数据库管理系统中的日期函数返回每个季度的开始日期和结束日期即可。我们的目标是生成如下所示的结果集,这里以生成当前年份的记录为例。

QTR Q_START     Q_END
--- ----------- -----------
  1 01-JAN-2005 31-MAR-2005
  2 01-APR-2005 30-JUN-2005
  3 01-JUL-2005 30-SEP-2005
  4 01-OCT-2005 31-DEC-2005

DB2
同时使用 EMP 表和窗口函数 ROW_NUMBER OVER 生成 4 行纪录。除此之外,也可以使用 WITH 子句达到同样目的(正如许多实例的做法一样),甚至也可以借助任何行数不少于 4 行的表。下面的解决方案选择使用 ROW_NUMBER OVER 函数。

 1  select quarter(dy-1 day) QTR,
 2         dy-3 month Q_start,
 3         dy-1 day Q_end
 4    from (
 5  select (current_date -
 6           (dayofyear(current_date)-1) day
 7             + (rn*3) month) dy
 8    from (
 9  select row_number()over() rn
10    from emp
11   fetch first 4 rows only
12         ) x
13         ) y

Oracle
使用 ADD_MONTHS 函数找到每个季度的开始日期和结束日期。使用 ROWNUM 代表每个开始日期和结束日期分别属于哪个季度。下面的解决方案借助 EMP 表生成 4 行记录。

1 select rownum qtr,
2        add_months(trunc(sysdate,'y'),(rownum-1)*3) q_start,
3        add_months(trunc(sysdate,'y'),rownum*3)-1 q_end
4   from emp
5  where rownum <= 4

PostgreSQL
使用 GENERATE_SERIES 函数生成所需的 4 个季度。使用 DATE_TRUNC 函数对每个季度的日期做截断处理,使之仅精确到年份和月份。使用 TO_CHAR 函数计算出每一对开始日期和结束日期分别属于哪个季度。

 1  select to_char(dy,'Q') as QTR,
 2         date(
 3           date_trunc('month',dy)-(2*interval '1 month')
 4         ) as Q_start,
 5         dy as Q_end
 6    from (
 7  select date(dy+((rn*3) * interval '1 month'))-1 as dy
 8    from (
 9  select rn, date(date_trunc('year',current_date)) as dy
10    from generate_series(1,4) gs(rn)
11         ) x
12         ) y

MySQL
使用 T500 表生成 4 行数据(每个季度一行)。使用 DATE_ADDADDDATE 函数计算出每个季度的开始日期和结束日期。使用 QUARTER 函数计算出每一对开始和结束日期分别属于哪个季度。

 1  select quarter(adddate(dy,-1)) QTR,
 2         date_add(dy,interval -3 month) Q_start,
 3         adddate(dy,-1) Q_end
 4    from (
 5  select date_add(dy,interval (3*id) month) dy
 6    from (
 7  select id,
 8         adddate(current_date,-dayofyear(current_date)+1) dy
 9    from t500
10   where id <= 4
11         ) x
12         ) y

SQL Server
使用 WITH 递归查询生成 4 行数据。使用 DATEADD 函数找出开始日期和结束日期。使用 DATEPART 函数计算出每一对开始日期和结束日期分别属于哪个季度。

 1  with x (dy,cnt)
 2    as (
 3 select dateadd(d,-(datepart(dy,getdate())-1),getdate()),
 4        1
 5   from t1
 6  union all
 7 select dateadd(m,3,dy), cnt+1
 8   from x
 9  where cnt+1 <= 4
10 )
11 select datepart(q,dateadd(d,-1,dy)) QTR,
12        dateadd(m,-3,dy) Q_start,
13        dateadd(d,-1,dy) Q_end
14   from x
15  order by 1

SQL 列出一年中每个季度的开始日期和结束日期 扩展知识

DB2
首先生成 4 行数据(取值为 1 到 4),每个季度一行。内嵌视图 X 使用窗口函数 ROW_NUMBER OVERFETCH FIRST 子句,仅返回 EMP 表的前 4 行数据,结果如下所示。

select row_number()over() rn
  from emp
 fetch first 4 rows only
 
RN
--
 1
 2
 3
 4

然后找出当前年份的第一天,然后加上 n 个月,nRN 的 3 倍(分别在当前年份第一天的基础上加上 3 个月、6 个月、9 个月和 12 个月),结果如下所示。

select (current_date -
         (dayofyear(current_date)-1) day
           + (rn*3) month) dy
  from (
select row_number()over() rn
  from emp
 fetch first 4 rows only
       ) x
 
DY
-----------
01-APR-2005
01-JUL-2005
01-OCT-2005
01-JAN-2006

现在,DY 的值就是每个季度最后一天再加上 1 天的日期。下一步要计算出每个季度的开始日期和结束日期。DY 值减去 1 天就是每个季度的结束日期,DY 减去 3 个月就是每个季度的开始日期。针对 DY-1 的值(每个季度的最后一天)调用 QUARTER 函数,计算出每一对开始日期和结束日期分别属于哪个季度。
Oracle
把函数 ROWNUMTRUNCADD_MONTHS 组合起来使用,就能很容易地解决本问题。为找出每个季度的开始日期,只要在当前年份第一天的基础上加上 n 个月即可,n(ROWNUM-1)*3(计算结果分别是 0、3、6 和 9)。为找出每个季度的结束日期,在当前年份第一天的基础上分别加上 n 个月再减去 1 天,n 等于 ROWNUM*3。顺便多说一句,做季度相关的计算时,函数 TO_CHARTRUNC 搭配上格式化选项 q 非常有用。
PostgreSQL
首先调用 DATE_TRUNC 函数截断当前日期,得到当前年份第一天。然后,加上 n 个月再减去 1 天,nRNGENERATE_SERIES 函数的返回值)的 3 倍。结果如下所示。

select date(dy+((rn*3) * interval '1 month'))-1 as dy
  from (
select rn, date(date_trunc('year',current_date)) as dy
  from generate_series(1,4) gs(rn)
       ) x
 
DY
-----------
31-MAR-2005
30-JUN-2005
30-SEP-2005
31-DEC-2005

现在得到了每个季度的结束日期,下一步要找出开始日期,用 DY 减去 2 个月,并调用 DATE_TRUNC 函数做截断处理即可。最后,针对每个季度的最后一天(DY)调用 TO_CHAR 函数,计算出每一对开始日期和结束日期分别属于哪个季度。
MySQL
首先调用 ADDDATEDAYOFYEAR 函数找出当前年份的第一天,然后调用 DATE_ADD 函数在当前年份第一天的基础上加上 n 个月,n 等于 T500.ID 乘以 3。结果如下所示。

select date_add(dy,interval (3*id) month) dy
  from (
select id,
       adddate(current_date,-dayofyear(current_date)+1) dy
  from t500
 where id <= 4
       ) x
 
DY
-----------
01-APR-2005
01-JUL-2005
01-OCT-2005
01-JAN-2006

现在得到了每个季度最后一天再加上 1 天的日期;为了找出每个季度的结束日期,只要用 DY 值减去 1 天即可。下一步要找出每个季度的开始日期,从 DY 值里减去 3 个月即可。在每个季度结束日期的基础上调用 QUARTER 函数计算出每一对开始日期和结束日期分别属于哪个季度。
SQL Server
首先找出当前年份的第一天,然后调用 DATEADD 函数逐次加上 n 个月,n 是当前迭代次数的 3 倍(共有 4 次迭代,因而分别加上了 3×1 个月,3×2 个月,等等)。结果如下所示。

with x (dy,cnt)
  as (
select dateadd(d,-(datepart(dy,getdate())-1),getdate()),
       1
  from t1
 union all
select dateadd(m,3,dy), cnt+1
  from x
 where cnt+1 <= 4
)
select dy
  from x
 
DY
-----------
01-APR-2005
01-JUL-2005
01-OCT-2005
01-JAN-2006

DY 值是每个季度最后一天再加上 1 天的日期。为得到每个季度的结束日期,只要调用 DATEADD 函数从 DY 里减去 1 天即可。为找出每个季度的开始日期,调用 DATEADD 函数从 DY 里减去 3 个月。借助 DATEPART 函数根据每个季度的结束日期计算出每一对开始日期和结束日期分别属于哪个季度。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程