Stored Procedure to generate work day prior?

  • 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!

  • 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/

    http://www.sqlservercentral.com/scripts/DateDiff/63346/

    If everything seems to be going well, you have obviously overlooked something.

    Ron

    Please help us, help you -before posting a question please read[/url]
    Before posting a performance problem please read[/url]

  • 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

  • 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.

    If everything seems to be going well, you have obviously overlooked something.

    Ron

    Please help us, help you -before posting a question please read[/url]
    Before posting a performance problem please read[/url]

  • Ron, just an FYI... the code came through with no carriage returns.

    And thanks for the awesome compliment! :blush:

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • 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

    If everything seems to be going well, you have obviously overlooked something.

    Ron

    Please help us, help you -before posting a question please read[/url]
    Before posting a performance problem please read[/url]

  • Just testing... please ignore this post....

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • 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


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

Viewing 8 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic. Login to reply