函数如下
CREATE OR REPLACE FUNCTION getLastYearDay(thisDt IN NUMBER) RETURN NUMBER
--
-- 指定日の一年前の同月同週を取得する。
-- in 指定日
-- return 前年同月同週日
--
IS
 -- 指定日
 dt DATE;
 -- 週の番号
 weekNo NUMBER;
 -- 同月同週の日
 returnDt DATE;
BEGIN
 -- 指定日をDATE型へ変換
 dt := TO_DATE(thisDt, 'YYYYMMDD');
 -- 週の番号を取得する。
weekNo := TRUNC(TO_CHAR(dt, 'DDD') / 7); -- 指定日の前年の元旦を設定
 returnDt := TO_DATE(TO_CHAR(ADD_MONTHS(dt, -12), 'YYYY') || '0101', 'YYYYMMDD');
 -- 曜日設定
 IF TO_CHAR(dt, 'D') >= TO_CHAR(returnDt, 'D') THEN
  returnDt := returnDt + (TO_CHAR(dt, 'D') - TO_CHAR(returnDt, 'D'));
 ELSE
  returnDt := returnDt + (TO_CHAR(dt, 'D') - TO_CHAR(returnDt, 'D')) + 7;
 END IF;
 -- 週の番号
 returnDt := returnDt + weekNo * 7; -- 戻り
 RETURN TO_NUMBER(TO_CHAR(returnDt, 'YYYYMMDD'));
END;比如:select getlastyearday(20090302) from dual
结果为:20080303
select getlastyearday(20090303) from dual
结果为:20080226 错误
应该为:20080304

解决方案 »

  1.   

    有这么复杂吗?
    year = year - 1;
    month = add_months(month,-12);
    day 根据 last_day自己算一下-1即可
      

  2.   


    就错了一句:
    weekNo   :=   TRUNC(TO_CHAR(dt,   'DDD ')   /   7); 
    应该为:
    weekNo   :=   TRUNC(TO_CHAR(dt,   'DDD ')   /   7)+1;
    不加一是不对的:) 参见正确的函数:CREATE OR REPLACE FUNCTION getLastYearDay(thisDt   IN   NUMBER)   RETURN   NUMBER
    IS 
      dt   DATE; 
      weekNo   NUMBER; 
      returnDt   DATE; 
    BEGIN   dt   :=   TO_DATE(thisDt,   'YYYYMMDD '); 
      weekNo   :=   TRUNC(TO_CHAR(dt,   'DDD ')   /   7)+1;   returnDt   :=   TO_DATE(TO_CHAR(ADD_MONTHS(dt,   -12),   'YYYY ')   ||   '0101 ',   'YYYYMMDD ');   IF   TO_CHAR(dt,   'D ')   >=   TO_CHAR(returnDt,   'D ')   THEN 
        returnDt   :=   returnDt   +   (TO_CHAR(dt,   'D ')   -   TO_CHAR(returnDt,   'D ')); 
      ELSE 
        returnDt   :=   returnDt   +   (TO_CHAR(dt,   'D ')   -   TO_CHAR(returnDt,   'D '))   +   7; 
      END   IF;   returnDt   :=   returnDt   +   weekNo   *   7;   RETURN   TO_NUMBER(TO_CHAR(returnDt,   'YYYYMMDD ')); 
    END;