Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 business day

Author  Topic 

igorblackbelt
Constraint Violating Yak Guru

407 Posts

Posted - 2006-06-27 : 14:17:35
Hey All -
I'm trying to update a column, whenever the day falls on a sat, sun or holiday, the field needs to be adjusted to the next business day, can you guys point me to the right direction ?

Should I make use of Stored Procedures or UDF ?

Thanks!


---

Thanks!
Igor.

DonAtWork
Master Smack Fu Yak Hacker

2167 Posts

Posted - 2006-06-27 : 14:53:17
See if any of these help.

http://www.sqlteam.com/item.asp?ItemID=3332
http://www.sqlteam.com/item.asp?ItemID=5857
http://www.sqlteam.com/item.asp?ItemID=2652


Help us help YOU!
Read this blog entry for more details: http://weblogs.sqlteam.com/brettk/archive/2005/05/25.aspx

*need more coffee*
SELECT * FROM Users WHERE CLUE > 0
(0 row(s) affected)
Go to Top of Page

cvraghu
Posting Yak Master

187 Posts

Posted - 2006-06-27 : 16:36:48
I assume that you've a table storing holiday list -

update table1
set businessday =
case
when lower(datename(dw,table1.businessday)) = 'saturday' then dateadd(dd,2,table1.businessday)
when lower(datename(dw,table1.businessday)) = 'sunday' then dateadd(dd,1,table1.businessday)
when lower(datename(dw,table1.businessday)) = 'friday' and
exists (select 'x' from holidays where holiday = table1.businessday) then dateadd(dd,3,table1.businessday)
when exists (select 'x' from holidays where holiday = table1.businessday) then dateadd(dd,1,table1.businessday)
end
Go to Top of Page

cvraghu
Posting Yak Master

187 Posts

Posted - 2006-06-27 : 16:47:32
The logic to arrive at the no of days to be added is not correct in the query. It does not consider the fact that it could be a holiday.

But you can think in these lines.
Go to Top of Page

rockmoose
SQL Natt Alfen

3279 Posts

Posted - 2006-06-27 : 16:58:47
Igor,

Do you have a date table, with holidays?
It would make things so much simpler.

I would consider the following options as well (not udf,sp)
1. Have a view that returns the date and the nextWorkDayDate
2. Have a trigger on the table that adjusts the data.
In 2) I would seriously consider storing the original date, and a column storing the calculated workDayDate as well.
3. A calculated column for the workDayDate, (similar solution to 2.)

rockmoose
Go to Top of Page

cvraghu
Posting Yak Master

187 Posts

Posted - 2006-06-27 : 18:54:21
You can make use of this recursive function -

create function getNextBusinessDay(@iDate datetime) returns datetime
as
begin
declare @ODate datetime
select @ODate =
case
when lower(datename(dw,@iDate)) = 'saturday' then dateadd(dd,2,@iDate)
when lower(datename(dw,@iDate)) = 'sunday' then dateadd(dd,1,@iDate)
when lower(datename(dw,@iDate)) = 'friday' and
exists (select 'x' from holidays where holiday = @iDate) then dateadd(dd,3,@iDate)
when exists (select 'x' from holidays where holiday = @iDate) then dateadd(dd,1,@iDate)
else @iDate
end

If Exists(Select 'X' from holidays where holiday = @ODate)
Select @ODate = dbo.getNextBusinessDay(@ODate)

return @ODate
end

update table1
set businessday = dbo.getNextBusinessDay(businessday)

If you want to update only the needed rows, make modifications to function and update statement as needed.
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2006-06-27 : 20:47:20
The update is fairly easy if you have a table of Work Days.

The code shows how to load the Work Days table from a Date table and and Holiday table.


The Date Table Function F_TABLE_DATE is available here:
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=61519


-- Select date range for update
declare @start_date datetime
declare @end_date datetime
-- 20 Days before today
select @start_date = dateadd(dd,datediff(dd,0, getdate()-20),0)
-- 40 Days after start date
select @end_date = @start_date+40

select [@start_date] = convert(varchar(10),@start_date,121),
[ @end_date] = convert(varchar(10),@end_date,121)

-- Holiday table
declare @holiday table
([DATE] datetime not null primary key clustered )

print '*** Load @holiday'
insert into @holiday
select '20060704' -- July 4th Holiday



-- Work Date Table
declare @WorkDate table
([WORK_DATE] datetime not null primary key clustered
)

print '*** Load @WorkDate'
-- Load table with Work Days
insert into @WorkDate
select
a.[DATE]
from
-- Date Table Function from Script Library
dbo.F_TABLE_DATE ( @start_date,@end_date) a
left join
@holiday b
on a.[DATE] = b.[DATE]
where
-- Select Monday through Friday
a.[DAY_OF_WEEK] between 2 and 6 and
-- Exclude Holidays
b.[DATE] is null

-- Test Data
declare @MyTable table (
MyTableID int identity(1,1) primary key clustered,
MyDate datetime not null
)


print '*** Load @MyTable'
-- Load test dates to be updated
insert into @MyTable (MyDate)
select '20060623' union all
select '20060624' union all
select '20060625' union all
select '20060626' union all
select '20060627' union all
select '20060628' union all
select '20060704'

print '*** @MyTable before update'
select * from @MyTable

print '*** Update @MyTable'
update a
set
a.MyDate =
( -- Update to earliest work date > MyDate
select
[DATE] = min(c.[WORK_DATE])
from
@WorkDate c
where
c.[WORK_DATE] > a.MyDate
)
from
@MyTable a
where
-- Select only dates in ramge
a.MyDate >= @start_date and
a.MyDate < (select max(z.[WORK_DATE]) from @WorkDate z ) and
-- Select rows that are not work days
a.MyDate not in
( select x.[WORK_DATE] from @WorkDate x )


print '*** @MyTable after update'
select * from @MyTable



Results:

start_date @end_date
----------- ----------
2006-06-07 2006-07-17

(1 row(s) affected)

*** Load @holiday

(1 row(s) affected)

*** Load @WorkDate

(28 row(s) affected)

*** Load @MyTable

(7 row(s) affected)

*** @MyTable before update
MyTableID MyDate
----------- ------------------------------------------------------
1 2006-06-23 00:00:00.000
2 2006-06-24 00:00:00.000
3 2006-06-25 00:00:00.000
4 2006-06-26 00:00:00.000
5 2006-06-27 00:00:00.000
6 2006-06-28 00:00:00.000
7 2006-07-04 00:00:00.000

(7 row(s) affected)

*** Update @MyTable

(3 row(s) affected)

*** @MyTable after update
MyTableID MyDate
----------- ------------------------------------------------------
1 2006-06-23 00:00:00.000
2 2006-06-26 00:00:00.000
3 2006-06-26 00:00:00.000
4 2006-06-26 00:00:00.000
5 2006-06-27 00:00:00.000
6 2006-06-28 00:00:00.000
7 2006-07-05 00:00:00.000

(7 row(s) affected)



CODO ERGO SUM
Go to Top of Page

rob_farley
Yak Posting Veteran

64 Posts

Posted - 2006-06-27 : 21:34:51
I feel like you're over-complicating things, which would be much simpler with an auxiliary table of numbers (a table of numbers from 0 up to some arbitrary number - I call my table 'nums', with a single int column 'num').

--First make sure you have a holidays table:

select '4-jul-2006' holiday_date into dbo.holidays;
insert into holidays values ('3-jul-2006');

--Then create your function

create function dbo.uf_nextbusinessday(@today datetime) returns datetime as
begin
declare @res datetime
declare @today_trunc datetime

--First truncate the date
set @today_trunc = cast(floor(cast(@today as float)) as datetime)

--Now find the first day which isn't either Saturday, Sunday, or a holiday
select @res = min(d.candidate) from
(select dateadd(day,n.num,@today_trunc) candidate from nums n where n.num < 7) d
left join
holidays h
on h.holiday_date = d.candidate
where h.holiday_date is null
and datepart(dw,d.candidate) not in (6,7)

return (@res)
end


--If you try populating a table of holidays with Jul 3rd and 4th, then this query should demonstrate success or not:

select d.theday, dbo.uf_nextbusinessday(d.theday) thebusinessday
from
(select dateadd(day,n.num,'1-jun-2006') theday from nums n where n.num < 40) d

I hope this helps...

Rob

Rob Farley
http://robfarley.blogspot.com
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2006-06-27 : 22:29:42
Rob, your computer must have a non-US setting, because 6 and 7 are not both weekend days under US settings, unless you consider Friday a weekend day.

This is why I do not like using functions that depend on a particular setting of DATEFIRST to return correct results.


select
DT = convert(varchar(10), DT,121),
DW = datepart(dw,dt),
DName= datename(dw,DT)
from
(select DT = getdate()+4 union all select DT = getdate()+3) a



Results:

DT DW DName
---------- ----------- ------------------------------
2006-07-01 7 Saturday
2006-06-30 6 Friday

(2 row(s) affected)






CODO ERGO SUM
Go to Top of Page

byrmol
Shed Building SQL Farmer

1591 Posts

Posted - 2006-06-27 : 22:43:35
>>....unless you consider Friday a weekend day.

Rob's an Aussie Michael, so when the the surf's up and the sun is hot, everyday is the weekend...

DavidM

Intelligent Design is NOT science.

A front-end is something that tries to violate a back-end.
Go to Top of Page

rob_farley
Yak Posting Veteran

64 Posts

Posted - 2006-06-27 : 22:44:35
Ah - yes... I'm in Australia, where many calendars start on Mondays.

So use this instead:

and (datepart(dw,d.candidate) + @@datefirst)%7 not in (0,1)
--replaces: and datepart(dw,d.candidate) not in (6,7)

Rob Farley
http://robfarley.blogspot.com
Go to Top of Page

rockmoose
SQL Natt Alfen

3279 Posts

Posted - 2006-06-28 : 03:39:53
quote:
Originally posted by byrmol

>>....unless you consider Friday a weekend day.

Rob's an Aussie Michael, so when the the surf's up and the sun is hot, everyday is the weekend...

DavidM



Seems I was born on the wrong side of the globe

rockmoose
Go to Top of Page

rob_farley
Yak Posting Veteran

64 Posts

Posted - 2006-06-28 : 03:42:09
:) I wasn't born here. And I'm English on the inside.

Rob Farley
http://robfarley.blogspot.com
Go to Top of Page

igorblackbelt
Constraint Violating Yak Guru

407 Posts

Posted - 2006-07-05 : 11:56:50
wow guys, I guess I forgot this topic hehe, I used a function that I found on SQLServerCentral, and that's been working pretty well, I'll review every and each post from you guys to see if that works better on my scenario, thanks for the replies.

Here's the link to the UDF I spoke about:
http://www.sqlservercentral.com/columnists/rScholl/findingthenextbusinessdayrecursively.asp

And aswering to some of the questions, yes, I do have a Holidays table.



---

Thanks!
Igor.
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2006-07-05 : 12:11:03
Here's my 2 cents

http://weblogs.sqlteam.com/brettk/archive/2005/05/12/5139.aspx



Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx

Add yourself!
http://www.frappr.com/sqlteam
Go to Top of Page
   

- Advertisement -