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