• KTTHOOL (4/4/2009)


    The problem is that the SQL SERVER 2005 stores in yy/dd/mm format.

    No, the problem is that you think it does, and it does not. SQL SERVER 2005 stores dates as datetime. Even your own DOB column which you defined in your first post:

    Table -> Person

    Field -> DOB

    type -> datetime

    Computed-> no

    Nullable-> yes

    There's no need to convert it to a string or anything else, just use the built-in DATETIME functions:

    -- make up some sample DOB data

    DECLARE @person TABLE (id INT, name VARCHAR(100), dob DATETIME)

    INSERT INTO @person

    SELECT 1, 'p1', '1948-12-30 00:00:00.000'

    UNION SELECT 2, 'p2', '1958-12-31 00:00:00.000'

    UNION SELECT 3, 'p3', '1968-01-01 00:00:00.000'

    UNION SELECT 4, 'p4', '1982-01-02 00:00:00.000'

    UNION SELECT 5, 'p5', '2004-04-04 00:00:00.000' -- Happy Birthday to me!

    UNION SELECT 6, 'p6', '2005-04-16 00:00:00.000' -- 12 days away

    UNION SELECT 7, 'p7', '2006-04-25 00:00:00.000' -- 21 days away

    UNION SELECT 8, 'p8', '2007-05-05 00:00:00.000'

    UNION SELECT 9, 'p9', '2008-05-20 00:00:00.000'

    UNION SELECT 10, 'p10', '2009-05-25 00:00:00.000'

    -- show how the algorith works

    DECLARE @Today DATETIME, -- allows you to change the "current date" for testing

    @WarningDays INT

    SET @Today = DATEDIFF(DAY, 0, GETDATE()) -- set the time-stripped "current date"

    SET @WarningDays = 15

    SELECT *,

    DATEDIFF(YEAR, dob, @Today), -- number of year boundaries crossed since DOB

    DATEADD(yy, DATEDIFF(YEAR, dob, @Today), dob), -- add to DOB to give birthday this year

    DATEDIFF(dd, @Today, DATEADD(yy, DATEDIFF(YEAR, dob, @Today), dob)) -- compare with current date to yield number of days until birthday

    FROM @person

    id name dob YearBounds Birthday DaysToBD

    ----------- ---- ----------------------- ----------- ----------------------- -----------

    1 p1 1948-12-30 00:00:00.000 61 2009-12-30 00:00:00.000 270

    2 p2 1958-12-31 00:00:00.000 51 2009-12-31 00:00:00.000 271

    3 p3 1968-01-01 00:00:00.000 41 2009-01-01 00:00:00.000 -93

    4 p4 1982-01-02 00:00:00.000 27 2009-01-02 00:00:00.000 -92

    5 p5 2004-04-04 00:00:00.000 5 2009-04-04 00:00:00.000 0

    6 p6 2005-04-16 00:00:00.000 4 2009-04-16 00:00:00.000 12

    7 p7 2006-04-25 00:00:00.000 3 2009-04-25 00:00:00.000 21

    8 p8 2007-05-05 00:00:00.000 2 2009-05-05 00:00:00.000 31

    9 p9 2008-05-20 00:00:00.000 1 2009-05-20 00:00:00.000 46

    10 p10 2009-05-25 00:00:00.000 0 2009-05-25 00:00:00.000 51

    -- use the algorithm

    DECLARE @Today DATETIME, -- allows you to change the "current date" for testing

    @WarningDays INT

    SET @Today = DATEDIFF(DAY, 0, GETDATE()) -- set the time-stripped "current date"

    SET @WarningDays = 15

    SELECT *,

    DATEDIFF(dd, @Today, DATEADD(yy, DATEDIFF(YEAR, dob, @Today), dob)) AS DaysToBD

    FROM @person

    WHERE DATEDIFF(dd, @Today, DATEADD(yy, DATEDIFF(YEAR, dob, @Today), dob)) BETWEEN 0 AND @WarningDays

    id name dob DaysToBD

    ----------- ---- ----------------------- -----------

    5 p5 2004-04-04 00:00:00.000 0

    6 p6 2005-04-16 00:00:00.000 12

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden