1.2017-01-05至2018-04-05 希望返回 每个月有几天,可以用一个函数或者存储过程来实现
2.因为有大量的数据需要处理,所以返回值需要有对应,也就是说输入(id,起始日期,结束日期) 就可以返回对应的id 每个月的天数: id 月份 天数
函数设计思路
--计算相差月份
循环{
--赋值当前日期(累加)
--计算当前年是否闰年
--追加当前年月和天数
--当前日期加1
}
函数内容
create or replace function GETMONTHANDDAYS(ID VARCHAR2,DATE_START in DATE, DATE_END in DATE) return varchar2 is
FunctionResult varchar2(2000) := '';
type num_list is varray(12) of VARCHAR2(2);
P_DAYS num_list := num_list('31','30','31','30','31','30','31','31','30','31','30','31');
P_DAYS_RUNNIAN num_list := num_list('31','29','31','30','31','30','31','31','30','31','30','31');
CUR_DATE DATE;
CUR_YEAR NUMBER;
CUR_MONTH NUMBER;
GE_MONTH NUMBER;
begin
select ceil(months_between(DATE_END,DATE_START)) INTO GE_MONTH FROM DUAL;
CUR_DATE := DATE_START;
if GE_MONTH>0 then
LOOP
EXIT WHEN GE_MONTH=0;
select extract(year from CUR_DATE) into CUR_YEAR FROM DUAL;
SELECT EXTRACT(MONTH FROM CUR_DATE) INTO CUR_MONTH FROM DUAL;
IF ((mod(CUR_YEAR, 4)=0 and mod(CUR_YEAR, 100)!= 0) or (mod(CUR_YEAR, 400) = 0)) then
FunctionResult := (FunctionResult||';'||ID||','||to_char(CUR_DATE,'yyyymm')||','||P_DAYS_RUNNIAN(CUR_MONTH));
ELSE
FunctionResult := (FunctionResult||';'||ID||','||to_char(CUR_DATE,'yyyymm')||','||P_DAYS(CUR_MONTH));
END IF;
CUR_DATE:= ADD_MONTHS(CUR_DATE,1);
GE_MONTH := GE_MONTH - 1;
END LOOP;
end if;
return(substr(FunctionResult,2));
end GETMONTHANDDAYS;
结果示例(只需要根据分号截取每一条看是不是你想要的)
可以让显示按行来显示吗?或者插入一个表中有三列,id 月份 天数?
select trunc(时间1- 时间2) from table_name;
我才发现,不对啊 2017-01-05至2018-04-05 这个日期得2017-01天数应该是27 2018-04 的颖是5天,怎么出来都是31和30天???
IF ((mod(CUR_YEAR, 4)=0 and mod(CUR_YEAR, 100)!= 0) or (mod(CUR_YEAR, 400) = 0)) then
IF (EXTRACT(month FROM CUR_DATE)==EXTRACT(month FROM DATE_START)) then
FunctionResult := (FunctionResult||';'||ID||','||to_char(CUR_DATE,'yyyymm')||','||(P_DAYS_RUNNIAN(CUR_MONTH)-EXTRACT(day FROM DATE_START));
ELSE
FunctionResult := (FunctionResult||';'||ID||','||to_char(CUR_DATE,'yyyymm')||','||P_DAYS_RUNNIAN(CUR_MONTH));
END IF
ELSE
IF (EXTRACT(month FROM CUR_DATE)==EXTRACT(month FROM DATE_END)) then
FunctionResult := (FunctionResult||';'||ID||','||to_char(CUR_DATE,'yyyymm')||','||EXTRACT(day FROM DATE_END));
ELSE
FunctionResult := (FunctionResult||';'||ID||','||to_char(CUR_DATE,'yyyymm')||','||P_DAYS(CUR_MONTH));
END IF
END IF;
--中间那一段改成这个试试