在oracle sql中创建日期差异的自定义函数,排除周末和节假日

2024-05-06

我需要计算两个日期之间的天数decimal, 不包括周末和节假日 by 使用自定义函数在 Oracle SQL 中。 网站上也有类似的问题;然而,正如我所看到的,它们都没有要求使用自定义函数将输出作为十进制。我需要小数的原因是为了之后能够使用/提取时间分量。如果已经有这样的问题,请分享链接。

尝试借助我在互联网上找到的附加内容编写如下函数感谢作者 https://sqljana.wordpress.com/2017/03/16/oracle-calculating-business-days-between-two-dates-in-oracle/。内部子查询单独工作正常,但它不能作为一个整体功能工作。

简而言之,这个想法是:

(计算开始日期和结束日期之间的日差)->(排除开始日期和结束日期之间的周末天数)->(排除开始日期和结束日期之间的周末天数)

当我尝试保存该函数时,出现错误PLS-00103: Encountered the symbol "end-of-file"。由于我已经是函数新手,可能缺少一些基本的东西。

最后,如果您对如何提高代码效率有任何建议,也请告诉我。

提前致谢!

CREATE OR REPLACE FUNCTION  NET_WORKING_DAYS (startdate IN DATE, enddate IN DATE)
RETURN NUMBER IS 
  WORKINGDAYS_BETWEEN NUMBER;
BEGIN

SELECT

    -- number of days between startdate and enddate
      (
        SELECT (TO_DATE('20160831150000','YYYYMMDDHH24MISS')  - TO_DATE('20160801000000','YYYYMMDDHH24MISS') ) DAYS_BETWEEN 
        FROM DUAL
      )  
    -
    -- number of weekend days (after a given date)
      (
        SELECT COUNT(1)  WEEKEND_DAYS_BETWEEN
        FROM
        (
          SELECT
            TO_DATE('20160701000000','YYYYMMDDHH24MISS') + SEQ as day_date,     --2016/07/01 is a constant/given date for this formula
            TO_CHAR(TO_DATE('20160701000000','YYYYMMDDHH24MISS') + SEQ , 'D') day_of_week
          FROM
            (
                SELECT ROWNUM-1 SEQ
                FROM   ( SELECT 1 FROM  DUAL CONNECT BY LEVEL<= 365 * 5) --5 years
            )
          ORDER BY 1
        )
        WHERE day_of_week IN (6,7) 
          AND day_date > TO_DATE('20160801000000','YYYYMMDDHH24MISS')     --this should be replaced with startdate parameter
          AND day_date < TO_DATE('20160831000000','YYYYMMDDHH24MISS')      --this should be replaced with enddate parameter
      )  
    -
    -- number of holidays (after a given date)
      (
        SELECT COUNT(1)
        FROM HOLIDAYS
        WHERE HOLIDAY_DATE > TO_DATE('20160801000000','YYYYMMDDHH24MISS')     --this should be replaced with startdate parameter
          AND HOLIDAY_DATE < TO_DATE('20160831000000','YYYYMMDDHH24MISS')      --this should be replaced with enddate parameter
      )
INTO WORKINGDAYS_BETWEEN
FROM DUAL;

RETURN WORKINGDAYS_BETWEEN;
END NET_WORKING_DAYS;

**EDIT-1:假期已在数据库中的 HOLIDAYS 表中定义,并且此日期范围从20160801000000 to 20160831000000 , 30.06.2016是假期日期。


您不需要使用行生成器枚举每天来获取工作日数 - 可以使用简单的计算来完成:

From 我的回答在这里 https://stackoverflow.com/a/43633234/1509264:

CREATE FUNCTION getWorkingDays (
  in_start_date IN  DATE,
  in_end_date   IN  DATE
) RETURN NUMBER DETERMINISTIC
IS
  p_start_date   DATE;
  p_end_date     DATE;
  p_working_days NUMBER;
  p_holiday_days NUMBER;
BEGIN
  IF in_start_date IS NULL OR in_end_date IS NULL THEN
    RETURN NUll;
  END IF;

  p_start_date := LEAST( in_start_date, in_end_date );
  p_end_date   := GREATEST( in_start_date, in_end_date );

  -- 5/7 * ( Number of days between monday of the week containing the start date
  --         and monday of the week containing the end date )
  -- + LEAST( day of week for end date, 5 )
  -- - LEAST( day of week for start date, 5 )
  p_working_days := ( TRUNC( p_end_date, 'IW' ) - TRUNC( p_start_date, 'IW' ) ) * 5 / 7
                    + LEAST( p_end_date - TRUNC( p_end_date, 'IW' ), 5 )
                    - LEAST( p_start_date - TRUNC( p_start_date, 'IW' ), 5 );

  SELECT COALESCE(
           SUM(
             LEAST( p_end_date, holiday_date + INTERVAL '1' DAY )
             - GREATEST( p_start_date, holiday_date )
           ),
           0
         )
  INTO   p_holiday_days
  FROM   Holidays
  WHERE  HOLIDAY_DATE BETWEEN TRUNC( p_start_date )
                      AND     TRUNC( p_end_date )
  AND    HOLIDAY_DATE - TRUNC( HOLIDAY_DATE, 'IW' ) < 5;

  RETURN GREATEST( p_working_days - p_holiday_days, 0 );
END;
/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在oracle sql中创建日期差异的自定义函数,排除周末和节假日 的相关文章

随机推荐

  • 当存在多个字段分隔符时使用 AWK 忽略字段内的逗号

    我想像下面这样解析 CSV 记录awk or gawk 这些字段以逗号分隔 但最后一个字段 6 很特殊 因为它确实由子字段组成 这些子字段由 作为字段分隔符 或者 准确地说 分隔 这本身不是问题 我可以使用awk F 设置替代字段分隔符 但
  • 在所有布局方法之后调用哪个 Activity 方法?

    我需要做一些事情Activity调用所有布局方法后 所有Views 已就位并且Activity已准备好显示 哪种方法可以做到这一点 如果你想获得视图的宽度或其他东西 这应该有效 将其添加到您的 Activity 的 onCreate 中 V
  • WCF:Per-Call 和 Per-Session 服务...需要说服 Per-Call 是值得的

    我们目前正在审查 WCF 服务设计 困扰我的一件事是 Per Call 和 Per Session 服务之间的决定 我相信我理解两者背后的概念 但我并没有真正看到按呼叫服务的优势 我知道使用 Per Call 服务的动机是 WCF 服务仅在
  • 给 NSWindow 一个背景图片

    好的 我已经在 Photoshop 中创建了一个图像 该图像将与我的应用程序上的按钮对齐 现在我想将其作为窗口的背景图像 以便图像上的字符将对应于我的应用程序上的按键应用程序 我一直在开发的一个小型计算器演示应用程序 基本上 我没有给按钮提
  • 多线程:只有在执行完其他方法后才调用执行方法

    我正在尝试根据要求异步处理方法 一旦第一个方法完成 只有第二个方法应该开始执行 问题是第一个方法本身具有在后台线程上运行的代码 我尝试了dispatch semaphore wait 但这也不起作用 dispatch queue t que
  • 链接“let”语句时使用“and”还是“in”更好?

    我意识到这可能是一个愚蠢的问题 但是 如果我把一堆let不需要需要了解彼此价值观的语句 使用是否更好and or in 例如 以下哪一个更可取 如果有 let a foo and b bar and c baz in etc or let
  • Android 列表视图布局 类似于 Google play

    我想实现一个类似于 Google Play 的列表布局 其中每个行都有菜单 请帮助我创建这个 我是否需要创建一个弹出菜单或者有任何选项可以实现此目的 Thanks 看起来您正在尝试完全按照图中所示的方式进行操作 我只是举一个例子来说明我如何
  • JBoss AS 7 部署顺序和时间安排

    我对一般部署顺序和具体时间安排有疑问 我有一个 Ear 1 它通过 bean 和一些队列提供一些功能 队列在standalone xml 中配置 另一只耳朵 2 使用 Ear1 的此服务 所以依赖关系看起来像 ear1 因此 我将ear 2
  • 将一段文本保存到mysql

    我正在使用 php 和 mysql 做一个项目 我对此很陌生 现在我必须将一段文本存储到我的数据库中 在表中 对于列 I tried varchar 5000 创建表时但它不允许我 所以请给我一个解决方案 你的 mysql 字段类型应该 T
  • .NET Web API - 添加日志记录

    我正在寻找有关处理 API 日志记录的最佳方法的帮助 我想将所有请求和响应记录到 sql 或文本文件 如果这是最好的方法 目前我已经在 SQL Server 的日志表中插入一行 我使用名为 LogAction 的静态方法来执行此操作 并在
  • 无法比较类型“ndarray(dtype=int64)”和“str”

    Example of data that I want to replace 数据具有以下属性 购买 V 高 高 中 低 维持 V 高 高 中 低 门 2 3 4 5 更多 2 4人以上 lug boot 小 中 大 安全性低 中高 这就是
  • F# 中类型约束的顺序

    这适用于 F 4 0 type Something lt a b when b gt seq lt b gt gt 这不会 type Something lt b when b gt seq lt b gt a gt 类型名称中出现意外的符
  • 将项目添加到自定义组件的布局

    我有一个习惯Footer Component我想在 QML 应用程序的不同位置重用它 Rectangle color gold height 50 anchors bottom parent bottom left parent left
  • for循环内递归函数的时间复杂度

    如果我们有一个函数 int x 0 int fun int n if n 0 return 1 for int i 0 i
  • 在 C# 中调用并排显示窗口

    愚蠢的问题是否有一种简单的方法可以清除桌面 然后打开两个资源管理器窗口并调用 并排显示窗口 任务栏调用 只是想知道 MS 库中是否有 api 可以做到这一点 您可以使用TileWindowsWinAPI 函数通过 p invoke 将所需窗
  • Actionscript 对象的属性数量

    如何获取通用 Actionscript 对象中的属性数量 如数组长度 您必须循环所有元素才能对它们进行计数 function objectLength myObject Object int var cnt int 0 for var s
  • jQuery UI .buttonset() 太慢

    我的 HTML 页面上有几千个按钮 运行需要10多秒 buttonset buttonset 文件准备好 有没有更快的方法来做到这一点 或者是我以某种方式限制按钮数量的唯一解决方案 创建buttonset在第一次显示之前按需进行 我刚刚测试
  • 如何将谓词作为参数传递#

    如何将谓词传递到方法中 但在没有传递谓词的情况下仍使其工作 我想也许是这样的 但似乎并不正确 private bool NoFilter return true private List
  • 如果存在 sqlite 则重命名列?

    我创建了一个最初未使用的列 但现在我们正在设置和获取值 我发现列名不正确 以及我想要更改列名称但想要保留设备中现有数据库的数据 有任何疑问吗检查并重命名sqlite 列 像这样的东西 Alter Table MyTable RENAME C
  • 在oracle sql中创建日期差异的自定义函数,排除周末和节假日

    我需要计算两个日期之间的天数decimal 不包括周末和节假日 by 使用自定义函数在 Oracle SQL 中 网站上也有类似的问题 然而 正如我所看到的 它们都没有要求使用自定义函数将输出作为十进制 我需要小数的原因是为了之后能够使用