这是我将如何处理等效查询。通过将日期范围计算放入一个小的交叉连接查询中,您可以在查询的其余部分轻松访问结果。
SELECT
e.payroll_id AS payrollId
, cj. working_days
FROM employee e
cross join (
select
GREATEST(NEXT_DAY(start_date, 'MON') - start_date - 2, 0)
+ ((NEXT_DAY(end_date, 'MON') - NEXT_DAY(start_date, 'MON'))/7)*5
- GREATEST(NEXT_DAY(end_date, 'MON') - end_date - 3, 0)
- (
SELECT COUNT(holiday)
FROM admin_holiday
WHERE holiday_date BETWEEN start_date AND end_date
)
as working_days
FROM (
select
to_date('20170501','yyyymmdd') as start_date
, to_date('20170522','yyyymmdd') as end_date
from dual
)
) cj
WHERE e.DEL_FLAG = 1
ORDER BY e.payrollId
工作日逻辑是:
计算第一周的前导天数 +(计算周一/周五期间的数量)* 5 - 最后一周的尾随天数 - 表格中的额外假期:
select
GREATEST(NEXT_DAY(start_date, 'MON') - start_date - 2, 0)
+ ((NEXT_DAY(end_date, 'MON') - NEXT_DAY(start_date, 'MON'))/7)*5
- GREATEST(NEXT_DAY(end_date, 'MON') - end_date - 3, 0)
- (
SELECT COUNT(holiday)
FROM admin_holiday
WHERE holiday_date BETWEEN start_date AND end_date
)
as working_days
, start_date
, end_date
, holidays
, end_date - start_date
FROM (
select
trunc(sysdate,'MM') as start_date
, trunc(sysdate) as end_date
from dual
)
示例(这里没有零假期):
+--------------+--------------+-------------+------------+-------------------------+
| WORKING_DAYS | START_DATE | END_DATE | HOLIDAYS | END_DATE-START_DATE |
+--------------+--------------+-------------+------------+-------------------------+
| 16 | 01.05.2017 | 22.05.2017 | 0 | 21 |
+--------------+--------------+-------------+------------+-------------------------+
要手动设置日期,您可以这样做:
select
GREATEST(NEXT_DAY(start_date, 'MON') - start_date - 2, 0)
+ ((NEXT_DAY(end_date, 'MON') - NEXT_DAY(start_date, 'MON'))/7)*5
- GREATEST(NEXT_DAY(end_date, 'MON') - end_date - 3, 0)
- (
SELECT COUNT(holiday)
FROM admin_holiday
WHERE holiday_date BETWEEN start_date AND end_date
)
as working_days
FROM (
select
to_date('20170501','yyyymmdd') as start_date
, to_date('20170522','yyyymmdd') as end_date
from dual
)