我想创建一个日期列表,从今天的3年前的1月1日到12月31日,未来2年。在第二栏中,我想标记圣诞节(XMAS),新年前夜(NYE),新年(NYD),阵亡将士纪念日(MEM),7月4日(JUL4),劳动节(LABOR)。对于后3个假期,我不仅需要标注假日日期,还需要标注上周六的每一天,以便标记整个长周末。否则用工作日名称标记日期。
SELECT STAYDATE,
CASE
WHEN TO_CHAR(STAYDATE,'MM')=12 AND TO_CHAR(STAYDATE,'DD')=25 THEN 'XMAS'
WHEN TO_CHAR(STAYDATE,'MM')=12 AND TO_CHAR(STAYDATE,'DD')=31 THEN 'NYE'
WHEN TO_CHAR(STAYDATE,'MM')=01 AND TO_CHAR(STAYDATE,'DD')=01 THEN 'NYD'
WHEN TO_CHAR(STAYDATE,'MM')=7 AND TO_CHAR(STAYDATE,'DD')=04 THEN 'JUL4'
ELSE
TO_CHAR(STAYDATE,'dy') END DAYLABEL
FROM (
SELECT TRUNC (add_months(sysdate,24) - ROWNUM) STAYDATE
FROM DUAL CONNECT BY ROWNUM < 1000)
答案 0 :(得分:0)
查询1 :
buildTypes { release { shrinkResources true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
<强> Results 强>:
SELECT DT,
CASE
WHEN EXTRACT( MONTH FROM DT ) = 12
AND EXTRACT( DAY FROM DT ) = 25
THEN 'XMAS'
WHEN EXTRACT( MONTH FROM DT ) = 12
AND EXTRACT( DAY FROM DT ) = 31
THEN 'NYE'
WHEN EXTRACT( MONTH FROM DT ) = 1
AND EXTRACT( DAY FROM DT ) = 1
THEN 'NYD'
WHEN EXTRACT( MONTH FROM DT ) = 7
AND DT BETWEEN NEXT_DAY( TRUNC( DT, 'MM' ) - 4, 'SATURDAY' )
AND TRUNC( DT, 'MM' ) + 3
THEN 'JUL4'
WHEN EXTRACT( MONTH FROM DT ) = 9
AND DT BETWEEN NEXT_DAY( TRUNC( DT, 'MM' ) - 1, 'MONDAY' ) - 2
AND NEXT_DAY( TRUNC( DT, 'MM' ) - 1, 'MONDAY' )
THEN 'LABOR'
WHEN EXTRACT( MONTH FROM DT ) = 5
AND DT BETWEEN NEXT_DAY( TRUNC( LAST_DAY( DT ) ) - 7, 'MONDAY' ) - 2
AND NEXT_DAY( TRUNC( LAST_DAY( DT ) ) - 7, 'MONDAY' )
THEN 'MEM'
ELSE TO_CHAR( DT, 'DY' )
END AS day
FROM (
SELECT ADD_MONTHS( TRUNC( SYSDATE, 'YYYY' ), -36 ) + LEVEL - 1 AS DT
FROM DUAL
CONNECT BY
ADD_MONTHS( TRUNC( SYSDATE, 'YYYY' ), -36 ) + LEVEL - 1
< ADD_MONTHS( TRUNC( SYSDATE, 'YYYY' ), +24 )
)
答案 1 :(得分:0)
您还可以使用SCHEDULE个对象。在我看来,Calendaring Syntax提供了比本机DATE功能更多的灵活性。
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('LABOR_DAY', repeat_interval => 'FREQ=YEARLY;BYDATE=0501');
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('NEW_YEARS_EVE', repeat_interval => 'FREQ=YEARLY;INTERVAL=1;BYDATE=1231');
END;
然后你会使用与此类似的日程表:
DECLARE
next_run_date TIMESTAMP;
BEGIN
FOR aSchedule IN (SELECT * FROM USER_SCHEDULER_SCHEDULES WHERE SCHEDULE_NAME IN ('CHRISTMAS_DAY','NEW_YEARS_EVE','NEW_YEARS_DAY','INDEPENDENCE_DAY','MEMORIAL_DAY','LABOR_DAY') ) LOOP
next_run_date := ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), -36);
LOOP
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING(aSchedule.REPEAT_INTERVAL, NULL, next_run_date, next_run_date);
EXIT WHEN next_run_date > ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 12)-1;
DBMS_OUTPUT.PUT_LINE( TO_CHAR(next_run_date, 'YYYY-MM-DD ')||aSchedule.SCHEDULE_NAME );
IF TO_CHAR(next_run_date, 'Dy', 'nls_date_language=american') = 'Fri' AND aSchedule.SCHEDULE_NAME IN ('INDEPENDENCE_DAY','MEMORIAL_DAY','LABOR_DAY') THEN
DBMS_OUTPUT.PUT_LINE( TO_CHAR(next_run_date+1, 'YYYY-MM-DD ')||aSchedule.SCHEDULE_NAME );
DBMS_OUTPUT.PUT_LINE( TO_CHAR(next_run_date+2, 'YYYY-MM-DD ')||aSchedule.SCHEDULE_NAME );
END IF;
END LOOP;
END LOOP;
END;
2015-12-25 CHRISTMAS_DAY
2016-12-25 CHRISTMAS_DAY
2017-12-25 CHRISTMAS_DAY
2018-12-25 CHRISTMAS_DAY
2015-07-04 INDEPENDENCE_DAY
2016-07-04 INDEPENDENCE_DAY
2017-07-04 INDEPENDENCE_DAY
2018-07-04 INDEPENDENCE_DAY
2015-05-01 LABOR_DAY
2015-05-02 LABOR_DAY
2015-05-03 LABOR_DAY
2016-05-01 LABOR_DAY
2017-05-01 LABOR_DAY
2018-05-01 LABOR_DAY
2015-05-25 MEMORIAL_DAY
2016-05-30 MEMORIAL_DAY
2017-05-29 MEMORIAL_DAY
2018-05-28 MEMORIAL_DAY
2016-01-01 NEW_YEARS_DAY
2017-01-01 NEW_YEARS_DAY
2018-01-01 NEW_YEARS_DAY
2015-12-31 NEW_YEARS_EVE
2016-12-31 NEW_YEARS_EVE
2017-12-31 NEW_YEARS_EVE
2018-12-31 NEW_YEARS_EVE