PostgreSQL 使用 generate_series 生成日历

官方文档:PostgreSQL: Documentation: 14: 9.25. Set Returning Functions

generate_series ( start integerstop integer [, step integer ] ) → setof integer

generate_series ( start bigintstop bigint [, step bigint ] ) → setof bigint

generate_series ( start numericstop numeric [, step numeric ] ) → setof numeric

Generates a series of values from start to stop, with a step size of stepstep defaults to 1.

generate_series ( start timestampstop timestampstep interval ) → setof timestamp

generate_series ( start timestamp with time zonestop timestamp with time zonestep interval ) → setof timestamp with time zone

Generates a series of values from start to stop, with a step size of step.

总的来说 就是  generate_series(起始值,结束值,步长) 默认步长为1

样例:

--生成5以内的奇数列
select  generate_series(1,5,2) rn 

rn|
--+
 1|
 3|
 5|
 
 --默认步长
 select  generate_series(1,5) rn
 
 rn|
--+
 1|
 2|
 3|
 4|
 5|
 
-- 生成日期范围 步长为 天
select generate_series('20220101'::date,'20220105'::date,'+1 day') dd;

dd              |
-----------------------------+
2022-01-01 00:00:00.000 +0800|
2022-01-02 00:00:00.000 +0800|
2022-01-03 00:00:00.000 +0800|
2022-01-04 00:00:00.000 +0800|
2022-01-05 00:00:00.000 +0800|

--生成日期范围 步长为 月 
select generate_series('20220101'::date,'20221001'::date,'+1 month') dd;

dd              |
-----------------------------+
2022-01-01 00:00:00.000 +0800|
2022-02-01 00:00:00.000 +0800|
2022-03-01 00:00:00.000 +0800|
2022-04-01 00:00:00.000 +0800|
2022-05-01 00:00:00.000 +0800|
2022-06-01 00:00:00.000 +0800|
2022-07-01 00:00:00.000 +0800|
2022-08-01 00:00:00.000 +0800|
2022-09-01 00:00:00.000 +0800|
2022-10-01 00:00:00.000 +0800|

-- 一周的开始时间(周一)
select date_trunc('week','20220807'::date) 

date_trunc                   |
-----------------------------+
2022-08-01 00:00:00.000 +0800|


-- 第多少周
方式一:select extract(week from '20220807'::date)

extract|
-------+
     31|
     
方式二: select date_part('week','20220807'::date) 
date_part|
---------+
     31.0|

--星期 (1-6:星期1-6  0:星期日)
select extract(dow from '20220807'::date) 

extract|
-------+
      0|

-- 星期(1-7:星期1-星期日)      
select extract(isodow from '20220807'::date)  

extract|
-------+
      7|

生成日历

-- 一年的日期列表
with all_day as (
   select generate_series('20220101'::date,'20221231'::date,'+1 day') dd
),
w as (
  select to_char(dd,'yyyy-mm-dd') dd,
  --星期
  extract(dow from dd) ww,
  --月份
  extract(month from dd) mm,
  --基于周一,重新算第几周(杜绝跨年的情况,日期很小,但周很大)
  dense_rank() over(order by date_trunc('week',dd)) we 
  from all_day
)
select 
  case when row_number() over(partition by mm order by mm,we) = 1 then mm||'月' else '' end 月份,
  max(case when ww =1 then dd else '' end) 星期一,
  max(case when ww =2 then dd else '' end) 星期二,
  max(case when ww =3 then dd else '' end) 星期三,
  max(case when ww =4 then dd else '' end) 星期四,
  max(case when ww =5 then dd else '' end) 星期五,
  max(case when ww =6 then dd else '' end) 星期六,
  max(case when ww =0 then dd else '' end) 星期日
  from w
  group by mm,we

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值