如何使用 plpgsql 函数将实际月份划分为 5 天
how to divide actual months to 5 days periods using plpgsql function
我需要使用 posgrees 获取每月每五天的第一天。例如,如果 no 是 2.03,那么我将得到 1.03。如果今天是 19.03,那么我会得到 15.03。我尝试使用以下 if 语句,但在今天;那天我得到了 null,我不确定为什么。也肯定有一些不太复杂的方法来完成这个操作。有什么想法吗?
create or replace function getFirstDayOfFive()
returns timestamp with time zone as $$
declare
firstDay timestamp;
begin
if (now()::date>date_trunc('month', now()::date) and now()::date < date_trunc('month', now()::date) + interval '5 day') then
return firstDay = date_trunc('month', now()::date);
elsif (now()::date>date_trunc('month', now()::date) + interval '5 day' and now()::date < date_trunc('month', now()::date) + interval '10 day') then
return firstDay = (date_trunc('month', now()::date) + interval '5 day')::date;
elsif (now()::date>date_trunc('month', now()::date) + interval '10 day' and now()::date < date_trunc('month', now()::date) + interval '15 day') then
return firstDay = (date_trunc('month', now()::date) + interval '10 day')::date;
elsif (now()::date>date_trunc('month', now()::date) + interval '15 day' and now()::date < date_trunc('month', now()::date) + interval '20 day') then
return firstDay = (date_trunc('month', now()::date) + interval '15 day')::date;
elsif (now()::date>date_trunc('month', now()::date) + interval '20 day' and now()::date < date_trunc('month', now()::date) + interval '25 day') then
return firstDay = (date_trunc('month', now()::date) + interval '20 day')::date;
end if;
end;
$$
language plpgsql;
SELECT
make_date( -- 4
date_part('year', my_date)::int, -- 3
date_part('month', my_date)::int,
greatest( -- 2
floor(date_part('day', my_date) / 5) * 5, -- 1
1
)::int
)
- 使用
date_part()
获取当前日期的第几天。在它用 floor(day / 5) * 5
舍入到完整的倍数 5 之后
- 所提供的算法始终给出 5 的前一个倍数(对于
19
,它给出 15
,对于 6
,它给出 5
,...)。但是,对于 1
到 4
天,它给出了 0
。所以这是一个需要处理的异常。这是在这里完成的
- 获取当前日期的年月部分
- 创建预期日期。
这个查询当然可以嵌入到一个函数中:
create or replace function getFirstDayOfFive()
returns timestamp with time zone as $$
declare
firstDay timestamp;
begin
SELECT
make_date(
date_part('year', now())::int,
date_part('month', now())::int,
greatest(
floor(date_part('day', now()) / 5) * 5,
1
)::int
)
INTO firstDay;
RETURN firstDay;
end;
$$
language plpgsql;
编辑:来自评论:最后一天相同:
你必须改变:
floor()
到 ceil()
- 把
greatest(..., 1)
改成least(..., last day of current month)
要获得当月的最后一天,您必须使用 date_trunc('month', ...)
找到第一天,加上一个月得到下个月的第一天并从中减去一天:
SELECT
least(
ceil(date_part('day', now()) / 5) * 5,
date_part('day', date_trunc('month', now()) + interval '1 month - 1 day')
)
我需要使用 posgrees 获取每月每五天的第一天。例如,如果 no 是 2.03,那么我将得到 1.03。如果今天是 19.03,那么我会得到 15.03。我尝试使用以下 if 语句,但在今天;那天我得到了 null,我不确定为什么。也肯定有一些不太复杂的方法来完成这个操作。有什么想法吗?
create or replace function getFirstDayOfFive()
returns timestamp with time zone as $$
declare
firstDay timestamp;
begin
if (now()::date>date_trunc('month', now()::date) and now()::date < date_trunc('month', now()::date) + interval '5 day') then
return firstDay = date_trunc('month', now()::date);
elsif (now()::date>date_trunc('month', now()::date) + interval '5 day' and now()::date < date_trunc('month', now()::date) + interval '10 day') then
return firstDay = (date_trunc('month', now()::date) + interval '5 day')::date;
elsif (now()::date>date_trunc('month', now()::date) + interval '10 day' and now()::date < date_trunc('month', now()::date) + interval '15 day') then
return firstDay = (date_trunc('month', now()::date) + interval '10 day')::date;
elsif (now()::date>date_trunc('month', now()::date) + interval '15 day' and now()::date < date_trunc('month', now()::date) + interval '20 day') then
return firstDay = (date_trunc('month', now()::date) + interval '15 day')::date;
elsif (now()::date>date_trunc('month', now()::date) + interval '20 day' and now()::date < date_trunc('month', now()::date) + interval '25 day') then
return firstDay = (date_trunc('month', now()::date) + interval '20 day')::date;
end if;
end;
$$
language plpgsql;
SELECT
make_date( -- 4
date_part('year', my_date)::int, -- 3
date_part('month', my_date)::int,
greatest( -- 2
floor(date_part('day', my_date) / 5) * 5, -- 1
1
)::int
)
- 使用
date_part()
获取当前日期的第几天。在它用floor(day / 5) * 5
舍入到完整的倍数 5 之后
- 所提供的算法始终给出 5 的前一个倍数(对于
19
,它给出15
,对于6
,它给出5
,...)。但是,对于1
到4
天,它给出了0
。所以这是一个需要处理的异常。这是在这里完成的 - 获取当前日期的年月部分
- 创建预期日期。
这个查询当然可以嵌入到一个函数中:
create or replace function getFirstDayOfFive()
returns timestamp with time zone as $$
declare
firstDay timestamp;
begin
SELECT
make_date(
date_part('year', now())::int,
date_part('month', now())::int,
greatest(
floor(date_part('day', now()) / 5) * 5,
1
)::int
)
INTO firstDay;
RETURN firstDay;
end;
$$
language plpgsql;
编辑:来自评论:最后一天相同:
你必须改变:
floor()
到ceil()
- 把
greatest(..., 1)
改成least(..., last day of current month)
要获得当月的最后一天,您必须使用 date_trunc('month', ...)
找到第一天,加上一个月得到下个月的第一天并从中减去一天:
SELECT
least(
ceil(date_part('day', now()) / 5) * 5,
date_part('day', date_trunc('month', now()) + interval '1 month - 1 day')
)