谢谢您的阅读,这是情况
我有一个current_date和一个月中的某天,因此我要知道某个月的日期不是30和31,因此我需要知道该月的这一天的下一个日期。
示例:
预期结果:“ 2018-12-31”
目前我有这个:
create or replace function next_diff(vals int[], current_val int) returns int as
$$
declare v int;
declare o int := vals[1];
begin
foreach v in array vals loop
if current_val >= o and current_val < v then
return v - current_val;
end if;
o := v;
end loop;
return vals[1] - current_val;
end;
$$ language plpgsql;
这:
create or replace function next_day_of_month(days_of_month int[], curr_date date) returns date as
$$
declare cur_dom int := extract(day from curr_date);
declare next_diff int := next_diff(days_of_month, cur_dom);
begin
if next_diff < 0 then
curr_date := curr_date + '1 months'::interval;
end if;
curr_date := curr_date + (next_diff || 'days')::interval;
return curr_date;
end;
$$ language plpgsql;
但为此调用:
select next_day_of_month(array[31], '2018-09-24');
我正在:
“ 2018-10-01”
更多示例
如果我有这个值
我需要下个月的31号,但是我不能得到“ 2018-02-31”,因为2月没有31号,那么我应该得到“ 2018-02-31”,因为3月有31号。
结论
如果月份没有指定的日期,则必须忽略该月份并跳转到下一个日期。
感谢所有人
最终方法
使用卡洛斯·戈麦斯(Carlos Gomez)的答案,我创建了这个PostgreSQL函数并完美地工作:
create or replace function next_day_date(curr_date date, day_of_month int) returns date as
$$
declare next_day date;
begin
SELECT next_day_date into next_day FROM (
SELECT make_date_nullable(EXTRACT(year from n.month)::int, EXTRACT(month from n.month)::int, day_of_month) AS next_day_date
FROM (
SELECT generate_series(curr_date, curr_date + '3 months'::interval, '1 month'::interval) as month
) n
) results
WHERE results.next_day_date IS NOT NULL and results.next_day_date > curr_date LIMIT 1;
return next_day;
end;
$$ language plpgsql;
只需在where子句and results.next_day_date > curr_date
中添加其他过滤器,以防止在指定日期获得相同或先前的值
感谢大家的帮助
Thenks Carlos你是最好的
Gracias carlos eres el mejor:)
答案 0 :(得分:0)
您的示例并不完全匹配,但我想我知道您要解决的问题(您的第一个示例结果应为“ 2018-10-31”,因为十月份有31天,而第二个示例结果应为“ 2018-03-31')。似乎给定一个日期和一个月中的某天,您想查找具有该月中的下个月的下个月。为此,我将执行以下操作:
此函数仅包装make_date使其返回null,因为如果给定的日期超出范围(例如2月30日),它将引发异常。
CREATE OR REPLACE FUNCTION make_date_nullable(year int, month int, day int)
RETURNS date as $$
BEGIN
RETURN make_date(year, month, day);
EXCEPTION WHEN others THEN RETURN null;
END;
$$ language plpgsql;
此SELECT首先从当前月份开始生成接下来的三个月,然后使用您提供的day_of_month
来确定日期,最后得到第一个不为null的日期(根据postgresql存在。) >
SELECT next_day_date FROM (
SELECT make_date_nullable(EXTRACT(year from n.month)::int, EXTRACT(month from n.month)::int, day_of_month) AS next_day_date
FROM (
SELECT generate_series(current_date, current_date + '3 months'::interval, '1 month'::interval) as month
) n
) results
WHERE results.next_day_date IS NOT NULL LIMIT 1;
希望这会有所帮助!