【问题标题】:Oracle (10g) equivalent of DATEADD(weekday, -3, GETDATE())Oracle (10g) 相当于 DATEADD(weekday, -3, GETDATE())
【发布时间】:2011-08-05 22:13:17
【问题描述】:

我正在寻找 Oracle (10g) 等价物:

DATEADD(weekday, -3, GETDATE())

来自 T-SQL (SQL Server)。这个subtracts 3 weekdays 从当前日期开始。我不关心假期或类似的事情(我可以​​自己截断时间部分)。只排除周末就可以了。

【问题讨论】:

  • DATEADD(weekday, -3, GETDATE()) 的直接等价物是select trunc(sysdate) - 3 from dual。我意识到这已经得到了更详细的回答,但是我正在寻找这个简单的解决方案!

标签: oracle oracle10g date-arithmetic


【解决方案1】:

看来您需要创建一个 UDF。

CREATE OR REPLACE FUNCTION business_date (start_date DATE, 
days2add NUMBER) RETURN DATE IS
 Counter NATURAL := 0;
 CurDate DATE := start_date;
 DayNum POSITIVE;
 SkipCntr NATURAL := 0;
 Direction INTEGER := 1;  -- days after start_date
 BusinessDays NUMBER := Days2Add;
BEGIN
  IF Days2Add < 0 THEN
    Direction := - 1; -- days before start_date
    BusinessDays := (-1) * BusinessDays;
  END IF;

  WHILE Counter < BusinessDays LOOP
    CurDate := CurDate + Direction;
    DayNum := TO_CHAR( CurDate, 'D');

    IF DayNum BETWEEN 2 AND 6 THEN
      Counter := Counter + 1;
    ELSE
      SkipCntr := SkipCntr + 1;
    END IF;
  END LOOP;

  RETURN start_date + (Direction * (Counter + SkipCntr));
END business_date;

感谢拉里·本顿(Larry Benton),来自here

【讨论】:

    【解决方案2】:

    它可以在没有 PL/SQL 函数的情况下完成。只需根据星期几减去不同的天数:

    select trunc(sysdate) - case to_char(sysdate, 'D')
                            when '4' then 3 -- thursday minus 3 days
                            when '5' then 3 -- friday minus 3 days
                            when '6' then 4 -- saturday minus 4 days
                            else 5          -- all other days minus 5 days
                            end
    from dual;
    

    当您必须这样做时,例如12 天前,它看起来像:

    select trunc(sysdate) - case to_char(sysdate, 'D')
                            when '1' then 18 -- mondays minus 18 days (incl. 3 weekends)
                            when '2' then 18 -- tuesdays minus 18 days (incl. 3 weekends)
                            when '6' then 17 -- saturdays minus 17 days (incl. 2 weekends and a saturday)
                            else 16          -- all others minus 16 days (incl. 2 weekends)
                            end
    from dual;
    

    请注意,星期几取决于您数据库的 NLS_TERRITORY(在美国,第 1 天是星期日,在大多数其他国家,第 1 天是星期一)。

    【讨论】:

    • 应该注意的是,这只适用于少数天(如我的示例中的 3 天),其中多个周末不是一个因素。
    • 你能举个例子吗?我认为我的解决方案可以轻松调整为任意天数。
    • 当数字大于 5 时,您必须考虑多个周末,具体取决于您点击的数量。
    • @Cade Roux,逻辑没有改变。我在答案中添加了一个示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 2017-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多