可能有更好的方法可以做到这一点,并且考虑到您没有任何类型的 calendar 表,如果第四个星期五在当前周,则下面的查询将返回“Y”-
查询周开始 Sunday 并结束 Saturday
SELECT 'Y' FROM
(
SELECT max(to_date(month||' '||fri,'MON YYYY DD')) DT FROM (
SELECT LPAD( MONTH, 20-(20-LENGTH(MONTH))/2 ) MONTH,Sun, Mon, Tue,
Wed, Thu, Fri, Sat
FROM (SELECT TO_CHAR(dt,'fmMonthfm YYYY') MONTH,TO_CHAR(dt+1,'iw') week,
MAX(DECODE(TO_CHAR(dt,'d'),'1',LPAD(TO_CHAR(dt,'fmdd'),2))) Sun,
MAX(DECODE(TO_CHAR(dt,'d'),'2',LPAD(TO_CHAR(dt,'fmdd'),2))) Mon,
MAX(DECODE(TO_CHAR(dt,'d'),'3',LPAD(TO_CHAR(dt,'fmdd'),2))) Tue,
MAX(DECODE(TO_CHAR(dt,'d'),'4',LPAD(TO_CHAR(dt,'fmdd'),2))) Wed,
MAX(DECODE(TO_CHAR(dt,'d'),'5',LPAD(TO_CHAR(dt,'fmdd'),2))) Thu,
MAX(DECODE(TO_CHAR(dt,'d'),'6',LPAD(TO_CHAR(dt,'fmdd'),2))) Fri,
MAX(DECODE(TO_CHAR(dt,'d'),'7',LPAD(TO_CHAR(dt,'fmdd'),2))) Sat
FROM ( SELECT TRUNC(SYSDATE,'y')-1+ROWNUM dt
FROM all_objects
WHERE ROWNUM <= ADD_MONTHS(TRUNC(SYSDATE,'y'),12) - TRUNC(SYSDATE,'y'))
GROUP BY TO_CHAR(dt,'fmMonthfm YYYY'), TO_CHAR( dt+1, 'iw' ))
ORDER BY TO_DATE( MONTH, 'Month YYYY' ), TO_NUMBER(week))
where to_char(to_date(month,'MON YYYY'),'MON YYYY') = to_char(sysdate,'MON YYYY')
and fri is not null
and rownum <= 4) a
where a.dt BETWEEN sysdate+(8 - to_char(sysdate,'d'))-7
AND sysdate+(7 - to_char(sysdate,'d'));
要检查第 N 天 - 只需替换 rownum <= N 并将 and fri is not null 子句更改为 and <your_day> is not null,并将 SELECT to_date(month||' '||fri,'MON YYYY DD') DT FROM .. 更改为 SELECT to_date(month||' '||<your_day>,'MON YYYY DD') DT FROM ..。
因此,仅包含 day 和 N 值的动态查询可以获得所需的结果。喜欢
SELECT 'Y' FROM
(
SELECT max(to_date(month||' '||:day,'MON YYYY DD')) DT FROM (
SELECT LPAD( MONTH, 20-(20-LENGTH(MONTH))/2 ) MONTH,Sun, Mon, Tue,
Wed, Thu, Fri, Sat
FROM (SELECT TO_CHAR(dt,'fmMonthfm YYYY') MONTH,TO_CHAR(dt+1,'iw') week,
MAX(DECODE(TO_CHAR(dt,'d'),'1',LPAD(TO_CHAR(dt,'fmdd'),2))) Sun,
MAX(DECODE(TO_CHAR(dt,'d'),'2',LPAD(TO_CHAR(dt,'fmdd'),2))) Mon,
MAX(DECODE(TO_CHAR(dt,'d'),'3',LPAD(TO_CHAR(dt,'fmdd'),2))) Tue,
MAX(DECODE(TO_CHAR(dt,'d'),'4',LPAD(TO_CHAR(dt,'fmdd'),2))) Wed,
MAX(DECODE(TO_CHAR(dt,'d'),'5',LPAD(TO_CHAR(dt,'fmdd'),2))) Thu,
MAX(DECODE(TO_CHAR(dt,'d'),'6',LPAD(TO_CHAR(dt,'fmdd'),2))) Fri,
MAX(DECODE(TO_CHAR(dt,'d'),'7',LPAD(TO_CHAR(dt,'fmdd'),2))) Sat
FROM ( SELECT TRUNC(SYSDATE,'y')-1+ROWNUM dt
FROM all_objects
WHERE ROWNUM <= ADD_MONTHS(TRUNC(SYSDATE,'y'),12) - TRUNC(SYSDATE,'y'))
GROUP BY TO_CHAR(dt,'fmMonthfm YYYY'), TO_CHAR( dt+1, 'iw' ))
ORDER BY TO_DATE( MONTH, 'Month YYYY' ), TO_NUMBER(week))
where to_char(to_date(month,'MON YYYY'),'MON YYYY') = to_char(sysdate,'MON YYYY')
and :day is not null
and rownum <= :num) a
where a.dt BETWEEN sysdate+(8 - to_char(sysdate,'d'))-7
AND sysdate+(7 - to_char(sysdate,'d'));
如果您仔细看,子查询中有一个完整的日历。哪个是-
SELECT LPAD( MONTH, 20-(20-LENGTH(MONTH))/2 ) MONTH,Sun, Mon, Tue,
Wed, Thu, Fri, Sat
FROM (SELECT TO_CHAR(dt,'fmMonthfm YYYY') MONTH,TO_CHAR(dt+1,'iw') week,
MAX(DECODE(TO_CHAR(dt,'d'),'1',LPAD(TO_CHAR(dt,'fmdd'),2))) Sun,
MAX(DECODE(TO_CHAR(dt,'d'),'2',LPAD(TO_CHAR(dt,'fmdd'),2))) Mon,
MAX(DECODE(TO_CHAR(dt,'d'),'3',LPAD(TO_CHAR(dt,'fmdd'),2))) Tue,
MAX(DECODE(TO_CHAR(dt,'d'),'4',LPAD(TO_CHAR(dt,'fmdd'),2))) Wed,
MAX(DECODE(TO_CHAR(dt,'d'),'5',LPAD(TO_CHAR(dt,'fmdd'),2))) Thu,
MAX(DECODE(TO_CHAR(dt,'d'),'6',LPAD(TO_CHAR(dt,'fmdd'),2))) Fri,
MAX(DECODE(TO_CHAR(dt,'d'),'7',LPAD(TO_CHAR(dt,'fmdd'),2))) Sat
FROM ( SELECT TRUNC(SYSDATE,'y')-1+ROWNUM dt
FROM all_objects
WHERE ROWNUM <= ADD_MONTHS(TRUNC(SYSDATE,'y'),12) - TRUNC(SYSDATE,'y'))
GROUP BY TO_CHAR(dt,'fmMonthfm YYYY'), TO_CHAR( dt+1, 'iw' ))
ORDER BY TO_DATE( MONTH, 'Month YYYY' ), TO_NUMBER(week);