如何在 PostgreSQL 中按自定义三个月 date_trunc?

How to date_trunc by custom trimester in PostgreSQL?

我正在开展一个项目,其中财政年度按三个月衡量,听起来很奇怪,每个三个月都是从每月的第 10 天而不是第 1 天开始计算的,这是由于国家/地区的规定。因此,第一个三个月被认为是从 1 月 10 日开始,到三个月后的 9 日结束。有没有办法 date_trunc 或简单地使用 PostgreSQL 中的这些自定义三个月对时间戳列进行分组?

到目前为止,我只能通过 month/day/week 查询数据,例如:

FROM myTable SELECT( SUM(price) as total, date_trunc('month', 'timpestamp') ) GROUP BY (total)

yo可以加入result agants prepared intervals, eg:

t=# select starts,starts+'3 month'::interval ends,mod(ord,4) from  generate_series('2015-10-01'::date,'2018-10-01'::date,'3 month'::interval) with ordinality t(starts,ord);
         starts         |          ends          | mod
------------------------+------------------------+-----
 2015-10-01 00:00:00+00 | 2016-01-01 00:00:00+00 |   1
 2016-01-01 00:00:00+00 | 2016-04-01 00:00:00+00 |   2
 2016-04-01 00:00:00+00 | 2016-07-01 00:00:00+00 |   3
 2016-07-01 00:00:00+00 | 2016-10-01 00:00:00+00 |   0
 2016-10-01 00:00:00+00 | 2017-01-01 00:00:00+00 |   1
 2017-01-01 00:00:00+00 | 2017-04-01 00:00:00+00 |   2
 2017-04-01 00:00:00+00 | 2017-07-01 00:00:00+00 |   3
 2017-07-01 00:00:00+00 | 2017-10-01 00:00:00+00 |   0
 2017-10-01 00:00:00+00 | 2018-01-01 00:00:00+00 |   1
 2018-01-01 00:00:00+00 | 2018-04-01 00:00:00+00 |   2
 2018-04-01 00:00:00+00 | 2018-07-01 00:00:00+00 |   3
 2018-07-01 00:00:00+00 | 2018-10-01 00:00:00+00 |   0
 2018-10-01 00:00:00+00 | 2019-01-01 00:00:00+00 |   1
(13 rows)

在这里你可以使用 rownum 顺序的余数除以学期数来得到学期号(当然你需要处理 0 - 要么称之为 4,要么从减去一个学期开始并只使用 mod(ord,4)+1, 或者使用 case when 等等)

使用函数(或其中的表达式):

create or replace function get_trimester(timestamp)
returns integer language sql immutable as $$
    select (extract('month' from ::date- 9)::int- 1)/ 3 + 1
$$;

检查某些日期的函数:

with my_table(t) as (
values 
    ('2017-01-09'::timestamp),
    ('2017-01-10'),
    ('2017-04-09'),
    ('2017-04-10'),
    ('2017-07-09'),
    ('2017-07-10'),
    ('2017-10-09'),
    ('2017-10-10'),
    ('2017-12-31')
)

select t, get_trimester(t)
from my_table

          t          | get_trimester 
---------------------+---------------
 2017-01-09 00:00:00 |             4
 2017-01-10 00:00:00 |             1
 2017-04-09 00:00:00 |             1
 2017-04-10 00:00:00 |             2
 2017-07-09 00:00:00 |             2
 2017-07-10 00:00:00 |             3
 2017-10-09 00:00:00 |             3
 2017-10-10 00:00:00 |             4
 2017-12-31 00:00:00 |             4
(9 rows)