如何使用Oracle查询获得USA Holidays?

时间:2017-04-21 04:03:16

标签: oracle

我最近被要求提出一个返回美国假期的Oracle查询。做了一些研究后,我找不到这方面的任何东西。发现的大多数解决方案都是针对C#或VB。

2 个答案:

答案 0 :(得分:2)

您可以使用Oracle内置的SCHEDULER SCHEDULE。首先,你必须创建假期时间表,这里有一些例子:

BEGIN

    DBMS_SCHEDULER.CREATE_SCHEDULE('NEW_YEARS_DAY', repeat_interval => 'FREQ=YEARLY;INTERVAL=1;BYDATE=0101');
    DBMS_SCHEDULER.CREATE_SCHEDULE('MARTIN_LUTHER_KING_DAY', repeat_interval => 'FREQ=MONTHLY;BYMONTH=JAN;BYDAY=3 MON', comments => 'Third Monday of January');
    DBMS_SCHEDULER.CREATE_SCHEDULE('WASHINGTONS_BIRTHDAY', repeat_interval => 'FREQ=MONTHLY;BYMONTH=FEB;BYDAY=3 MON', comments => 'Third Monday of February');
    DBMS_SCHEDULER.CREATE_SCHEDULE('MEMORIAL_DAY', repeat_interval => 'FREQ=MONTHLY;BYMONTH=MAY;BYDAY=-1 MON', comments => 'Last Monday of May');
    DBMS_SCHEDULER.CREATE_SCHEDULE('INDEPENDENCE_DAY', repeat_interval => 'FREQ=YEARLY;INTERVAL=1;BYDATE=0704');
    DBMS_SCHEDULER.CREATE_SCHEDULE('CHRISTMAS_DAY', repeat_interval => 'FREQ=YEARLY;INTERVAL=1;BYDATE=1225');
    DBMS_SCHEDULER.CREATE_SCHEDULE('SPRING_BREAK', repeat_interval => 'FREQ=YEARLY;BYDATE=0301+SPAN:7D');

    DBMS_SCHEDULER.CREATE_SCHEDULE('ALL_HOLIDAYS', repeat_interval => 'FREQ=DAILY;INTERSECT=CHRISTMAS_DAY,INDEPENDENCE_DAY,MARTIN_LUTHER_KING_DAY,MEMORIAL_DAY,NEW_YEARS_DAY,SPRING_BREAK,WASHINGTONS_BIRTHDAY');

END;

请参阅此处的日历语法:Calendaring Syntax

然后您可以使用DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING

查询它们

示例:下一个阵亡将士纪念日

DECLARE
    start_time TIMESTAMP := TRUNC(LOCALTIMESTAMP);
    next_run_date TIMESTAMP := start_time;
BEGIN
    DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('MEMORIAL_DAY', NULL, next_run_date, next_run_date);
    DBMS_OUTPUT.PUT_LINE ( next_run_date );
END;

示例:今年的所有假期

DECLARE
    start_time TIMESTAMP := TIMESTAMP '2016-12-31 00:00:00';
    next_run_date TIMESTAMP := start_time;
BEGIN
    LOOP
        DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('ALL_HOLIDAYS', NULL, next_run_date, next_run_date);
        EXIT WHEN next_run_date > TIMESTAMP '2017-12-31 00:00:00';
        DBMS_OUTPUT.PUT_LINE ( next_run_date );
    END LOOP;
END;

示例:接下来10华盛顿的生日

DECLARE
    start_time TIMESTAMP := TRUNC(LOCALTIMESTAMP);
    next_run_date TIMESTAMP := start_time;
BEGIN
    FOR i IN 1..10 LOOP
        DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('WASHINGTONS_BIRTHDAY', NULL, next_run_date, next_run_date);
        DBMS_OUTPUT.PUT_LINE ( next_run_date );
    END LOOP;
END;

答案 1 :(得分:1)

下面我正在分享查询。请记住,在某些州,您可能会有更多的假期,但我只想通过列出最相关的节目来保留它。

/*
    New Year's Day -------------- January 1st
    Martin Luther King, Jr. ----- Third Monday in January
    Washington's Birthday ------- Third Monday in February
    Memorial Day ---------------- Last Monday in May
    Independence Day ------------ July 4th
    Labor Day ------------------- First Monday in September
    Columbus Day ---------------- Second Monday in October
    Veterans Day ---------------- November 11
    Thanksgiving Day ------------ Fourth Thursday in November
    Christmas Day --------------- December 25th
*/

SELECT NEXT_DAY(TRUNC(SYSDATE, 'YYYY') - 1, 'MONDAY') FROM DUAL UNION
SELECT NEXT_DAY(TRUNC(SYSDATE, 'YYYY') - 1, 'MONDAY') + 14 FROM DUAL UNION
SELECT NEXT_DAY(ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 1) - 1, 'MONDAY') + 14 FROM DUAL UNION
SELECT NEXT_DAY(ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 5) - 1, 'MONDAY') - 7 FROM DUAL UNION
SELECT ADD_MONTHS(TRUNC(SYSDATE,'YYYY'),6) + 3 FROM DUAL UNION
SELECT NEXT_DAY(ADD_MONTHS(TRUNC(SYSDATE,'YYYY'),8), 'MONDAY') FROM DUAL UNION
SELECT NEXT_DAY(ADD_MONTHS(TRUNC(SYSDATE,'YYYY'),9) - 1, 'MONDAY') + 7 FROM DUAL UNION
SELECT ADD_MONTHS(TRUNC(SYSDATE,'YYYY'),10) + 10 FROM DUAL UNION
SELECT NEXT_DAY(ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 10) - 1, 'THURSDAY') + 21 FROM DUAL UNION
SELECT ADD_MONTHS(TRUNC(SYSDATE,'YYYY'),11) + 24 FROM DUAL;