2014-02-26 83 views
1

我想搜索出生日期来自我的sql服务器数据库表。问题我得到的是年DOB将有所不同,将比今年晚。如果我想获取其生日将在未来7天内与Facebook生日提醒相同的客户列表。如何使用sql查询搜索birthdate?

我试图smalldatetime转换为varchar和使用LIKE语句“_” 通配符。例如Convert(Char(10),DOB,103) LIKE "__/02/____'。但是,它给我列出了当月DOB即将到来的客户。同时它还显示了本月之前生日的数据。我只想要那些未来7天生日即将到来的数据。

我的应用程序开发于C#。如果可能的话使用DataTableDataView得到适当的结果,那么请给我建议。

+0

可能重复的[SQL SELECT近期生日](http://stackoverflow.com/questions/83531/sql-select-upcoming-birthdays)检查[本答案](http://stackoverflow.com/questions/83531/sql-select-upcoming-birthdays/83783#83783) – Damith

回答

2

使用this method of date assembly,这应该工作:

SELECT * 从客户那里 DATEADD(日,DAY(DOB)-1, DATEADD(月,MONTH(DOB) - 1, DATEADD(一年,YEAR(CURRENT_TIMESTAMP) - 1900,0))) CURRENT_TIMESTAMP和DATEADD之间(DD,7,CURRENT_TIMESTAMP);

编辑
以上不适用于整个年份的变化。 这个呢,虽然是相当笨拙(使用@Today测试场景,然后代替CURRENT_TIMESTAMP完成时):

DECLARE @Today DATE = '31 Dec 2013'; 
select * 
from Customers 
CROSS JOIN 
    (
     SELECT YEAR(@Today) AS yr 
     UNION 
     SELECT YEAR(DATEADD(d, 7, @Today)) 
    ) years 
where 
    DATEADD(day, DAY(DOB) -1, 
      DATEADD(month, MONTH(DOB) - 1, 
       DATEADD(year, years.yr - 1900, 0))) 
    BETWEEN @Today AND DATEADD(DD, 7, @Today); 

SqlFiddle here

cross join将今年或在今年和明年,如果返回我们已经接近年底了,如果年份相同,UNION将确保只有一行。如果两年退还(即我们在十二月底),那么Between将排除今年1月份发生的客户的DOB:P必须有更优雅的解决方案,但是...

+0

为什么不只是将DOB和今天之间的差异加入到DOB中,并按照我的答案中发布的内容进行匹配?我以前使用过这种方法无数次,它始终工作100%... – FarligOpptreden

0

使用基于日期的函数。

//pseudo code 
Where Month(birthdate) = 7 
and Day(birthdate) = 4 

将拉动那些生于七月

+0

这不解决OP,而是匹配日期到特定的日期和月份。这个想法是在今天和今天之间的7天之间获得日期,所以你不能将它匹配到特定的日子和/或月份。 – FarligOpptreden

0

我不是我的开发机器上,所以这是未经测试的第四,但应该指向你在正确的方向。

SELECT * 
FROM TABLE 
WHERE MONTH(DOB) = MONTH(GETDATE()) AND 
(DAY(DOB) BETWEEN DAY(GETDATE()) AND 
DAY(DATEADD(dd, 7, GETDATE()))) 

注意,GETDATE()函数获取该计算机上当前时区的当前日期和时间。要使用UTC日期,请将GETDATE()替换为GETUTCDATE()

+1

这是行不通的,因为一旦跨越两个月,你就不会得到正确的数据。 – FarligOpptreden

+0

@FarligOpptreden好点。我没有考虑...... – HTX9

1

尝试使用DATEPARTDATEADDDATEDIFF函数为您的查询创建where子句。 WHERE子句中应该得到你想要的结果如下:

SELECT * 
FROM [Table] 
WHERE DATEADD(yy, DATEDIFF(yy, [DOB], GETDATE()) + 
      CASE 
       WHEN DATEPART(mm, GETDATE()) > 
        DATEPART(mm, DATEADD(dd, 7, GETDATE())) 
       AND DATEPART(mm, GETDATE()) <> DATEPART(mm, [DOB]) 
        THEN 1 
       ELSE 0 
      END, [DOB]) 
     BETWEEN GETDATE() AND DATEADD(dd, 7, GETDATE()) 

that从句做什么,是移动[DOB]值使用DATEADDDATEDIFF当年,从今天今天和7天之间进行匹配。

编辑:修改了条款以适应周期在一年的时间段。

+0

这似乎也错过了今天是12月31日的边缘情况,并且在1月的第一个星期有一个顾客的生日即将到来? [SqlFiddle](http://www.sqlfiddle.com/#!6/c6675/1)(小提琴更新) – StuartLC

+0

使http://www.sqlfiddle.com/#!6/16105/1 – StuartLC

+0

忙于修改后的答案 - 只是经过测试,你是对的。 – FarligOpptreden

0

使用StuartLC的示例作为基准。如何为每条记录创建DOB,而不是实际的年份,使用当年和明年。通过这种方式,您可以在两个日期中将DateDiff作为七天范围 - 处理年度滚动并对其意图非常明确。

实施例:

DECLARE @Today DATE = '31 Dec 2013'; 

SELECT * 
FROM Customers 
WHERE 
     cast(
      cast(Month(DOB) AS varchar) + '/' + 
      cast(Day(DOB) AS varchar) + '/' + 
      cast(Year(@Today) AS varchar) AS Date) BETWEEN @Today AND dateadd(day, 7, @Today) 
OR 
     cast(
      cast(Month(DOB) AS varchar) + '/' + 
      cast(Day(DOB) AS varchar) + '/' + 
      cast(Year(@Today) + 1 AS varchar) AS Date) BETWEEN @Today AND dateadd(day, 7, @Today) 

Sql Fiddle here