我正在尝试定位与今天匹配的上个月的日期。但是,目标日期需要基于当月剩余的相同工作日数。例如,如果今天是 14 年 6 月 6 日,那么我需要一个查询给我 14 年 5 月 7 日,因为这两个日期在各自的月份中还有 16 个工作日。另外,我正在使用 SQL Developer。
问问题
105 次
1 回答
1
有几种方法可以判断一天是工作日还是周末,但它们受 NLS 设置的约束。我在英国,因此我对 NLS_TERRITORY 的设置确定周六和周日是第 6 天和第 7 天。但是,其他地区(例如美国)将周日作为第 1 天。 了解更多。
无论如何,这个查询会生成从现在到 6 月底之间的工作日:
select weekday
from ( select weekday
, to_char(weekday,'D') as dayn
from ( select (sysdate + level) as weekday
from dual
connect by level <= (last_day(sysdate) - sysdate)
)
)
where dayn not in ('6','7')
/
...这给出了这个结果集...
8* where dayn not in ('6','7')
WEEKDAY
---------
09-JUN-14
10-JUN-14
...
26-JUN-14
27-JUN-14
30-JUN-14
16 rows selected.
SQL>
因此,我们可以将该逻辑包装在子查询中以获取天数,并使用一些LAST_DAY()、ADD_MONTHS() 和 TRUNC() 魔术 来生成上个月的类似列表。
with curr as ( select count(*) as nod
From
(
select weekday
from ( select weekday, to_char(weekday,'D') as dayn
from ( select sysdate + level weekday
from dual
connect by level <= (last_day(sysdate) - sysdate)
)
)
where dayn not in ('6','7')
)
)
, bds as ( select trunc(add_months(sysdate, -1), 'MM') fd
, last_day(add_months(sysdate, -1)) ld
from dual )
, prev as ( select weekday
, row_number() over (order by weekday desc) rn
from (
select fd + (level-1) weekday
from bds
connect by level <= ld-fd
)
where to_char(weekday,'D') not in ('6','7')
)
select prev.weekday
, rn
from prev
where prev.rn <= ( select nod+1 from curr )
order by prev.weekday
/
...在五月生成以下日期范围...
30* order by prev.weekday
WEEKDAY RN
--------- ----------
08-MAY-14 17
09-MAY-14 16
12-MAY-14 15
...
28-MAY-14 3
29-MAY-14 2
30-MAY-14 1
17 rows selected.
SQL>
现在,此范围与您建议的范围不匹配。那是因为圣灵。在英国,2014 年 5 月 26 日是银行假日。但是,Oracle 日期功能无法处理此类事情。因此,如果您想在计算中包括公共假期,则需要为它们创建一个参考表。我们可以像这样在子查询中包含该表:
, prev as ( select weekday
, row_number() over (order by weekday desc) rn
from (
select fd + (level-1) weekday
from bds
connect by level <= ld-fd
)
where to_char(weekday,'D') not in ('6','7')
and weekday not in ( select holiday from public_holidays )
)
...这给了我们这个结果集...
WEEKDAY RN
--------- ----------
07-MAY-14 17
08-MAY-14 16
...
28-MAY-14 3
29-MAY-14 2
30-MAY-14 1
17 rows selected.
SQL>
于 2014-06-08T08:56:49.433 回答