December 9, 2008 at 3:04 pm
I am developing a database that has certain tables organized by date/time, however these tables do not contain any entries for days that are not workdays (ie are weekends or holidays).
To avoid NULLS associated with missing days where there is no work, I'd like to create a stored procedure that I can give a date, and then have it return the date of the prior workday.
In math/set notation, this would be something like:
given a datetime object, date:
return: Max(d < date | ( ( datename(wd, d) not in {Saturday, Sunday} ) AND (d not in Holiday) )
where Holiday is a finite set of known holidays.
I'm still really new to SQL, so I'm having trouble getting my head around how I could prossibly write this, or if even a stored procedure is the right way to go about this.
Any ideas or thoughts are much appreciated.
Thanks!
December 9, 2008 at 3:25 pm
May I suggest your reading the following. The first is by Jeff Moden and is EXCELLENT
http://www.sqlservercentral.com/articles/Advanced+Querying/calculatingworkdays/1660/
December 10, 2008 at 9:02 am
You were right - Jeff's article was very helpful for handling weekends in the function I'm writing, but I still don't have a very efficient way to account for all the holidays.
Below is the function I have created that returns the prior Market Day based on the NYSE calendar for 2005-2010.
If anyone has a more efficient way of doing this, I would definitely appreciate being pointed in the right direction.
I've found the best date range to test this function is 12-20-2006 through 1-5-2007. There's a 3 day weekend (incl X-mas) and a 4 day weekend (New Yrs + memory of Gerald Ford) in there that the function needs to avoid.
Thanks!
----------------------------------------------------------
ALTER FUNCTION dbo.get_MarketDayPrior(@date SMALLDATETIME)
RETURNS SMALLDATETIME
AS
BEGIN
DECLARE
@AdjStart DATETIME,
@IntDays INT
SELECT @AdjStart=CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, @date)))
-- Calculates
SELECT @IntDays=1
SELECT @IntDays=@IntDays+
(CASE WHEN DATEPART(dw, @AdjStart-@IntDays)%6=1 THEN 1 ELSE 0 END
-- 2005 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2005-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-01-17' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-02-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-03-25' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-05-30' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-09-05' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-11-24' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-12-25' THEN 1 ELSE 0 END
-- 2006 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2006-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-01-16' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-02-20' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-04-14' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-05-29' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-09-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-11-23' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-12-25' THEN 1 ELSE 0 END
-- 2007 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-02' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-15' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-02-19' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-04-06' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-05-28' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-09-03' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-11-22' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-12-25' THEN 1 ELSE 0 END
-- 2008 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2008-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-01-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-02-18' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-03-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-05-26' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-09-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-11-27' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-12-25' THEN 1 ELSE 0 END
-- 2009 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2009-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-01-19' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-02-16' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-04-10' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-05-25' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-07-03' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-09-07' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-11-26' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-12-25' THEN 1 ELSE 0 END
-- 2010 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2010-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-01-18' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-02-15' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-04-02' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-05-31' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-07-05' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-09-06' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-11-24' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-12-24' THEN 1 ELSE 0 END
)
SELECT @IntDays=@IntDays+
(CASE WHEN DATEPART(dw, @AdjStart-@IntDays)%6=1 THEN 1 ELSE 0 END
-- 2005 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2005-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-01-17' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-02-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-03-25' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-05-30' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-09-05' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-11-24' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-12-25' THEN 1 ELSE 0 END
-- 2006 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2006-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-01-16' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-02-20' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-04-14' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-05-29' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-09-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-11-23' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-12-25' THEN 1 ELSE 0 END
-- 2007 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-02' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-15' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-02-19' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-04-06' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-05-28' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-09-03' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-11-22' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-12-25' THEN 1 ELSE 0 END
-- 2008 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2008-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-01-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-02-18' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-03-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-05-26' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-09-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-11-27' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-12-25' THEN 1 ELSE 0 END
-- 2009 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2009-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-01-19' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-02-16' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-04-10' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-05-25' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-07-03' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-09-07' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-11-26' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-12-25' THEN 1 ELSE 0 END
-- 2010 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2010-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-01-18' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-02-15' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-04-02' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-05-31' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-07-05' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-09-06' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-11-24' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-12-24' THEN 1 ELSE 0 END
)
SELECT @IntDays=@IntDays+
(CASE WHEN DATEPART(dw, @AdjStart-@IntDays)%6=1 THEN 1 ELSE 0 END
-- 2005 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2005-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-01-17' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-02-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-03-25' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-05-30' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-09-05' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-11-24' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-12-25' THEN 1 ELSE 0 END
-- 2006 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2006-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-01-16' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-02-20' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-04-14' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-05-29' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-09-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-11-23' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-12-25' THEN 1 ELSE 0 END
-- 2007 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-02' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-15' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-02-19' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-04-06' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-05-28' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-09-03' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-11-22' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-12-25' THEN 1 ELSE 0 END
-- 2008 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2008-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-01-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-02-18' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-03-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-05-26' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-09-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-11-27' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-12-25' THEN 1 ELSE 0 END
-- 2009 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2009-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-01-19' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-02-16' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-04-10' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-05-25' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-07-03' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-09-07' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-11-26' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-12-25' THEN 1 ELSE 0 END
-- 2010 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2010-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-01-18' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-02-15' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-04-02' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-05-31' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-07-05' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-09-06' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-11-24' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-12-24' THEN 1 ELSE 0 END
)
SELECT @IntDays=@IntDays+
(CASE WHEN DATEPART(dw, @AdjStart-@IntDays)%6=1 THEN 1 ELSE 0 END
-- 2005 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2005-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-01-17' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-02-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-03-25' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-05-30' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-09-05' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-11-24' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2005-12-25' THEN 1 ELSE 0 END
-- 2006 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2006-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-01-16' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-02-20' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-04-14' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-05-29' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-09-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-11-23' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2006-12-25' THEN 1 ELSE 0 END
-- 2007 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-02' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-01-15' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-02-19' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-04-06' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-05-28' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-09-03' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-11-22' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2007-12-25' THEN 1 ELSE 0 END
-- 2008 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2008-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-01-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-02-18' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-03-21' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-05-26' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-07-04' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-09-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-11-27' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2008-12-25' THEN 1 ELSE 0 END
-- 2009 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2009-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-01-19' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-02-16' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-04-10' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-05-25' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-07-03' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-09-07' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-11-26' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2009-12-25' THEN 1 ELSE 0 END
-- 2010 Holidays---------------
+ CASE WHEN (@AdjStart-@IntDays)='2010-01-01' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-01-18' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-02-15' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-04-02' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-05-31' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-07-05' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-09-06' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-11-24' THEN 1 ELSE 0 END
+ CASE WHEN (@AdjStart-@IntDays)='2010-12-24' THEN 1 ELSE 0 END
)
RETURN DATEADD(hh, 16, DATEADD(dd, -@IntDays, @AdjStart))
END
December 10, 2008 at 4:59 pm
bkmooney
Nice function and reasonably well commented. May I suggest adding the url for Jeff Moden's page -- as a comment of course. By this time next year if it were me, I would have forgottn what it was and then wondered about how I could account for weekends. But alas that is my poor memory. By the way I briefly tested your code and it works.
And please do not take this comment adversly. It was one heck of a lot of typing on your part and since it "hard codes" the holidays is some what inflexible. Should a new holiday be added to the NYSE calendar you would have to remember to edit the function.
So for grins I developed a function that uses a database table which I appropriately named NYSEHoliday. And wrote my function using the dates in the table, so as to make the function somewhat flexible. I have included it here as an attachment with the file type of .txt This will allow you to open it in notepad and read it before doing anything else... WARNING do NOT test the function on your production DB. My testing of my function was short and it should be tested, and tested and tested if you desire to adopt it for your use.
December 10, 2008 at 6:48 pm
Ron, just an FYI... the code came through with no carriage returns.
And thanks for the awesome compliment! :blush:
--Jeff Moden
Change is inevitable... Change for the better is not.
December 11, 2008 at 8:09 am
Per Jeff's comment here is my second attempt to show the function. As a side comment on my local machine openning the .txt file or even when it was in a .doc file using SSMS the carriage returns were all there.
Will someone, anyone instruct me in how to include the T- SQL text with carriage returns as an attached file.
USE [Test]
GO
/****** Object: Table [dbo].[NYSEHolidays] Script Date: 12/11/2008 10:01:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[NYSEHolidays]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[NYSEHolidays](
[Holiday] [smalldatetime] NOT NULL
) ON [PRIMARY]
END
GO
/****** Object: Index [IX_NYSE] Script Date: 12/11/2008 10:01:55 ******/
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[NYSEHolidays]') AND name = N'IX_NYSE')
CREATE UNIQUE NONCLUSTERED INDEX [IX_NYSE] ON [dbo].[NYSEHolidays]
(
[Holiday] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
IF NOT EXISTS (SELECT * FROM ::fn_listextendedproperty(N'MS_Description' , N'SCHEMA',N'dbo', N'TABLE',N'NYSEHolidays', N'COLUMN',N'Holiday'))
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Includes all NYSE holidays' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'NYSEHolidays', @level2type=N'COLUMN',@level2name=N'Holiday'
GO
/****** Object: UserDefinedFunction [dbo].[fn_PriorDay] Script Date: 12/11/2008 10:01:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_PriorDay]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
execute dbo.sp_executesql @statement = N'CREATE FUNCTION [dbo].[fn_PriorDay](@date SMALLDATETIME)
RETURNS SMALLDATETIME
AS
BEGIN
DECLARE
@AdjStart DATETIME,
@IntDays INT
SET @AdjStart=CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, @date)))
-- Calculates
SET @IntDays=1
SET @IntDays=@IntDays+
(CASE WHEN DATEPART(dw, @AdjStart-@IntDays)%6=1 THEN 1 ELSE 0 END)
WHILE EXISTS (SELECT holiday FROM NYSEholidays WHERE holiday = (@adjStart-@IntDays))
BEGIN
SET @IntDays = @IntDays + 1
END
RETURN DATEADD(hh, 16, DATEADD(dd, -@IntDays, @AdjStart))
END
'
END
December 11, 2008 at 9:07 pm
Just testing... please ignore this post....
--Jeff Moden
Change is inevitable... Change for the better is not.
December 11, 2008 at 9:10 pm
Ron,
I'm not sure what to tell you... I saved the file attached to the post above from SMS and renamed it .txt. That's all I did to it and it came through just fine.
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply