Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Usenet -> c.d.o.misc -> Re: Query help? Return the date which is n business days before d (from a table with all days in it)
On Mar 14, 7:45 pm, "sherifffruitfly" <sherifffruit..._at_gmail.com>
wrote:
> Hi all,
>
> I've got a table with columns:
>
> DATE (date type; contains all of the actual calendar days)
> IS_WORKDAY (0 or 1, depending on whether the DATE in that row is a
> work day)
>
> What I want:
>
> Suppose today is 1/20/2007. I want to know how many ACTUAL days back =
> 5 BUSINESS days back. For this example, the answer would be 6 (the
> 15th was apparently a holiday, according to our table).
>
> Another example: If today is a Monday, and I want the ACTUAL # of days
> corresponding to 1 BUSINESS day ago, three would be the answer
> (assuming Friday was a work day).
>
> What query will answer this question for me in general? A co-worker
> suggested the LAG function, but didn't have time to explain it to me
> in greater detail (and I don't totally follow the online
> documentation).
>
> This is going to be responding to a c# client, so hopefully an answer
> won't involve a lot of round-tripping.
>
> Thanks for any assistance,
>
> cdj
Table T holds 1 month here for clarity. THE_DAY is the day number in the entire year, you can use a TDateTime if you like instead.
BUS holds a flag saying whether the day is a business ('Y') or not ('N').
create table T (THE_DAY number, BUS varchar2(1));
insert into T values (1,'Y'); insert into T values (2,'N'); insert into T values (3,'N'); insert into T values (4,'Y'); insert into T values (5,'Y'); insert into T values (6,'Y'); insert into T values (7,'Y'); insert into T values (8,'Y'); insert into T values (9,'N'); insert into T values (10,'N'); insert into T values (11,'Y'); insert into T values (12,'Y'); insert into T values (13,'Y'); insert into T values (14,'Y'); insert into T values (15,'Y'); insert into T values (16,'N'); insert into T values (17,'N'); insert into T values (18,'Y'); insert into T values (19,'Y'); insert into T values (20,'Y'); insert into T values (21,'Y'); insert into T values (22,'Y'); insert into T values (23,'N'); insert into T values (24,'N'); insert into T values (25,'Y'); insert into T values (26,'Y'); insert into T values (27,'Y'); insert into T values (28,'Y'); insert into T values (29,'Y'); insert into T values (30,'N'); insert into T values (31,'N');
with ALL_BUS_DAYS as
( select THE_DAY, BUS, rownum R from
( select * from T
where BUS = 'Y'
order by THE_DAY ) ),
BUS_DAYS_FIVE_APART as
(
select B2.THE_DAY FIRST_BUS_DAY_BEFORE_DATE, B1.THE_DAY
FIFTH_BUS_DAY_BACK from ALL_BUS_DAYS B1 inner join ALL_BUS_DAYS B2
on B1.R = (B2.R - 5) -- <- change to 4 to used current day as one
business day
),
DAYS_WITH_LAST_BUS_DAYS as
(
select THE_DAY, BUS,
(select max(THE_DAY) from T T2 where T2.THE_DAY <= T.THE_DAY and BUS
= 'Y') LAST_BUS_N
from T
)
select THE_DAY, FIFTH_BUS_DAY_BACK, (THE_DAY - FIFTH_BUS_DAY_BACK) as
ACTUAL_DAYS_DIFF
from DAYS_WITH_LAST_BUS_DAYS inner join BUS_DAYS_FIVE_APART
on DAYS_WITH_LAST_BUS_DAYS.LAST_BUS_N =
BUS_DAYS_FIVE_APART.FIRST_BUS_DAY_BEFORE_DATE;
ANSWER:
THE_DAY FIFTH_BUS_DAY_BACK ACTUAL_DAYS_DIFF
---------- ------------------ ---------------- 8 1 7 9 1 8 10 1 9 11 4 7 12 5 7 13 6 7 14 7 7 15 8 7 16 8 8 17 8 9 18 11 7 19 12 7 20 13 7 21 14 7 22 15 7 23 15 8 24 15 9 25 18 7 26 19 7 27 20 7 28 21 7 29 22 7 30 22 8 31 22 9
Dean
ALL_BUS_DAYS gives the ordering row number of all the 'Y' days::
THE_DAY B R
---------- - ----------
1 Y 1 4 Y 2 5 Y 3 6 Y 4 7 Y 5 8 Y 6 11 Y 7 12 Y 8 13 Y 9 14 Y 10 15 Y 11 18 Y 12 19 Y 13 20 Y 14 21 Y 15 22 Y 16 25 Y 17 26 Y 18 27 Y 19 28 Y 20 29 Y 21
BUS_DAYS_FIVE_APART gives the day number of the current day with the day number of the 5th back business day, taking into account weekends and holidays ('N' days):
FIRST_BUS_DAY_BEFORE_DATE FIFTH_BUS_DAY_BACK
------------------------- ------------------ 8 1 11 4 12 5 13 6 14 7 15 8 18 11 19 12 20 13 21 14 22 15 25 18 26 19 27 20 28 21 29 22
DAYS_WITH_LAST_BUS_DAYS gives Received on Thu Mar 15 2007 - 00:52:39 CDT
![]() |
![]() |