阅读并尝试了很多sql代码之后,我仍然面临着这个问题。
我需要计算一个日期的第五个工作日。
我需要删除星期六' '周日'和美国假期
我有一张由美国假期组成的桌子,但是coudn能够在我的sql中正确加入它们
BDATE WEEKDAY_INDI
---------- --------------
1 6/1/2014 WEEKEND
2 6/2/2014 WEEKDAY
3 6/3/2014 WEEKDAY
4 6/4/2014 WEEKDAY
5 6/5/2014 WEEKDAY
6 6/6/2014 WEEKDAY
7 6/7/2014 WEEKEND
8 6/8/2014 WEEKEND
很明智,我可以在一张桌子/单独的桌子上获得工作日和假期
我有一个查询
select * from ODM.team
给出了
NAME DOB DOB_MONTH DOJ UPDATED_DATE
---------- ----------- ----------- ----------- --------------
1 Afnand 9/14/2000 September 2/20/2012 6/12/2014
2 Angil 10/9/2000 October 5/5/2014 6/10/2014
3 Asthwini 5/17/2000 May 4/6/2011 6/02/2014
我想计算下一个工作日UPDATED_DATE
因为我已经决定加入假期表和团队表,但它没有工作
您能否建议我如何获得下一个工作日(周末,节假日除外)。
答案 0 :(得分:0)
/*
with holidays as (
select bdate,
case when rnd = 1 then 'WEEKEND' else 'WEEKDAY' end weekday_indi
from (select trunc(sysdate) - lvl bdate, round(dbms_random.value(1,3)) rnd from (select level lvl
from dual connect by level <= 100)
)
),
team as (
select 1 name, trunc(sysdate) - 50 updated_date from dual
)
*/
select /* other t columns*/ name, updated_date, next5 from
(
select /* other t columns*/t.name, t.updated_date,
lead(decode(h.weekday_indi, 'WEEKEND', null, h.bdate) ignore nulls, 5)
over (partition by name order by h.bdate) next5,
row_number() over (partition by t.name order by h.bdate) rw
from team t left join holidays h on t.updated_date <= h.bdate
) where rw = 1;
您可以使用Oracle分析LEAD函数WITH IGNORE NULLS选项。
lead(decode(h.weekday_indi, 'WEEKEND', null, h.bdate) ignore nulls, 5)
- 如果是WEEKEND使bdate为null并找到第5个bdate,它比当前行更大(忽略空值)
如果HOLIDAYS表中没有bdate = updated_date,则可能无法正常工作
答案 1 :(得分:0)
我假设你有一个带有Window Aggregate方法的Oracle版本,特别是LEAD()
。
time_master
BDATE WEEKDAY_INDI
1 6/1/2014 WEEKEND
2 6/2/2014 WEEKDAY
3 6/3/2014 WEEKDAY
4 6/4/2014 WEEKDAY
5 6/5/2014 WEEKDAY
6 6/6/2014 WEEKDAY
7 6/7/2014 WEEKEND
8 6/8/2014 WEEKEND
队
NAME DOB DOB_MONTH DOJ UPDATED_DATE
1 Afnand 9/14/2000 September 2/20/2012 6/12/2014
2 Angil 10/9/2000 October 5/5/2014 6/10/2014
3 Asthwini 5/17/2000 May 4/6/2011 6/02/2014
以下SQL之类的东西可以帮助你入门。
SELECT t.*, LEAD(tm.BDATE, 5) OVER(PARTITION BY t.ID ORDER BY tm.BDATE)
FROM team t
INNER JOIN time_master tm
ON tm.BDATE >= t.UPDATED_DATE
AND tm.BDATE < t.UPDATED_DATE+10 --10 days to catch long weekends
AND tm.WEEKDAY_INDI = 'WEEKDAY'
答案 2 :(得分:0)
你是纯粹的sql还是pl / sql?这是你可以在pl / sql中尝试的伪代码:
updated_date DATE;
FOR i IN 1..5 outerloop
updated_date := updated_date + 1;
WHILE updated_date IN holidays.bdate
innerloop
updated_date := updated_date + 1;
END innerloop;
END outerloop;