如何在 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)
我正在开展一个项目,其中财政年度按三个月衡量,听起来很奇怪,每个三个月都是从每月的第 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)