两个日期之间的间隔

时间:2015-05-25 11:06:57

标签: sql database oracle date

我对Oracle中的日期有一些疑问。

是否可以获得两种DATE类型之间的间隔(以天为单位)?如果是,是否可以在此时间间隔内为每一天做一个声明(例如插入)?

我想过

while (a_sequence != difference_between_dates) 
LOOP 
a_sequence.next 
-- do things
END LOOP;

是否有可能获得具有周期性间隙的间隔? (比如每个周末。例如,Oracle中是否有模运算符?) 我认为像if(a_sequence % 6 || a_sequence % 7)之类的东西只是在周末做事情(假设较低的日期总是在星期一)。

第二天可以做my_date + 1吗?

3 个答案:

答案 0 :(得分:2)

不确定。如果您正在寻找PL / SQL解决方案(您可以在纯SQL中执行它,但它可能有点难以阅读),例如

DECLARE
  l_first_date date := date '2015-01-01';
  l_last_date  date := date '2015-12-31';
  l_date_to_check date;
BEGIN
  FOR i IN 1 .. l_last_date - l_first_date
  LOOP
    l_date_to_check := l_first_date + i;
    if( to_char( l_date_to_check, 'DY' ) IN ('SAT', 'SUN') )
    then
      <<do_something>>
    end if;
  END LOOP;
END;

这假设您的数据库使用的是英语语言环境(不同的语言显然在几天内有不同的缩写)。您可以通过在to_char函数中指定所需的NLS设置来使代码更加健壮,但对于大多数系统而言,这会增加代码的复杂性,这是不需要的。

答案 1 :(得分:1)

这段代码可以帮助你

    DECLARE
   first_date   DATE := TO_DATE ('01012015', 'DDMMYYYY');
   last_date    DATE := TO_DATE ('31012015', 'DDMMYYYY');
   a_sequence   NUMBER := 25;
BEGIN
   LOOP
      IF a_sequence = last_date - first_date
      THEN
         EXIT;
      END IF;

      DBMS_OUTPUT.put_line ('Sequence=' || a_sequence);
      a_sequence := a_sequence + 1;
   END LOOP;
END;

答案 2 :(得分:-1)

CREATE PROCEDURE `sp_calcula_intervalo`(
    IN `p_fl_frequency` VARCHAR(2),
    IN `p_dt_start` VARCHAR(10),
    IN `p_dt_ends` VARCHAR(10),
    OUT `p_qt_ocorrs` INT
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Calculates the interval between two dates'
BEGIN

    -- ------------------------------------------------------------------------------ 
    -- This code was written for Mysql
    -- ------------------------------------------------------------------------------ 
    --   Calculates the interval between two dates
    --   In Weeks, Fortnights, Months, Bimonths, Quarters, Semesters and Years
    --   CALL sp_calcula_intervalo('3M', '2020-01-31', '2020-05-31', @p_qt_ocorrs);
    -- ------------------------------------------------------------------------------

    -- ------------------------------------------------------------------------------
    -- Work Variables
    -- ------------------------------------------------------------------------------

    DECLARE dt_calc        DATE DEFAULT NULL;
    DECLARE dt_start           DATE DEFAULT NULL;
    DECLARE dt_ends              DATE DEFAULT NULL;
    DECLARE dt_proximo_mes      DATE DEFAULT NULL;

    DECLARE va_result        INT            DEFAULT 0;
    DECLARE va_msg              varchar(1000)  DEFAULT '';
    DECLARE va_end_loop              char(1)        DEFAULT 'N';

    DECLARE va_dd_start       char(2)  DEFAULT '00';
    DECLARE va_mm_start       char(2)  DEFAULT '00';

    DECLARE va_dt_next_mm_calc char(10)  DEFAULT '0000-00-00';
    DECLARE va_dd_calc            char(2)  DEFAULT '00';
    DECLARE va_mm_calc            char(2)  DEFAULT '00';

    -- ------------------------------------------------------------------------------
    -- Values Start
    -- ------------------------------------------------------------------------------

   SET va_dd_start = SUBSTR(p_dt_start, 9, 2);
   SET va_mm_start = SUBSTR(p_dt_start, 6, 2);

    SET dt_calc  = STR_TO_DATE(p_dt_start,'%Y-%m-%d'); 
    SET dt_start = STR_TO_DATE(p_dt_start,'%Y-%m-%d'); 
    SET dt_ends  = STR_TO_DATE(p_dt_ends,'%Y-%m-%d');

    SET va_result  = 1;

    -- ------------------------------------------------------------------------------
    -- Loop de Calc
    -- ------------------------------------------------------------------------------

    WHILE (va_end_loop = 'N') DO

        SELECT

            CASE  p_fl_frequency

                   WHEN '1M'  THEN ADDDATE(dt_calc,  INTERVAL 1 MONTH)
                   WHEN '2M'  THEN ADDDATE(dt_calc,  INTERVAL 2 MONTH)
                   WHEN '3M'  THEN ADDDATE(dt_calc,  INTERVAL 3 MONTH)
                   WHEN '4M'  THEN ADDDATE(dt_calc,  INTERVAL 4 MONTH)
                   WHEN '6M'  THEN ADDDATE(dt_calc,  INTERVAL 6 MONTH)
                   WHEN '12M' THEN ADDDATE(dt_calc,  INTERVAL 12 MONTH)
                   WHEN '1W'  THEN ADDDATE(dt_calc,  INTERVAL 1 WEEK)
                   WHEN '2W'  THEN ADDDATE(dt_calc,  INTERVAL 2 WEEK)

            END   INTO  dt_proximo_mes;

         SET va_result = va_result + 1;

         set va_dt_next_mm_calc = DATE_FORMAT(dt_proximo_mes, '%Y-%m-%d');
         SET va_dd_calc            = SUBSTR(va_dt_next_mm_calc, 9, 2);
         SET va_mm_calc            = SUBSTR(va_dt_next_mm_calc, 6, 2);

         if p_fl_frequency not in ('1W', '2W') then
             if va_dd_calc <> va_dd_start then

                if va_mm_calc <> '02' then -- Fevereiro

                   if va_mm_calc in ('04', '06', '09', '11') then  -- Meses com 30 dias
                      set va_dt_next_mm_calc = concat(SUBSTR(va_dt_next_mm_calc, 1, 8),'30');
                   else
                      if va_dd_start = '30' then
                         set va_dt_next_mm_calc = concat(SUBSTR(va_dt_next_mm_calc, 1, 8),'30');
                      else
                         set va_dt_next_mm_calc = concat(SUBSTR(va_dt_next_mm_calc, 1, 8),'31');
                      end if;
                   end if;
                end if;
             end if;
         end if;

            SET dt_calc = STR_TO_DATE(va_dt_next_mm_calc,'%Y-%m-%d');

          if dt_calc >= dt_ends then

             set va_end_loop = 'S';

             if dt_calc > dt_ends then
               SET va_result = va_result - 1;
             end if;

        end if;

    END WHILE;

    -- ------------------------------------------------------------------------------
    -- Return Calc
    -- ------------------------------------------------------------------------------

    select va_result as p_qt_ocorrs;

END