SQL选择即将到来的生日
我正在尝试编写一个存储过程来选择生日即将到来的员工。
从员工的生日中选择SELECT> @Today AND Birthday <@Today + @ NumDays`
这将不起作用,因为出生年份是生日的一部分,因此,如果我的生日是" 09-18-1983",则该年份不会介于" 09-18-2008"和" 09-25-2008"之间。
有没有一种方法可以忽略日期字段的年份部分,而只比较月/日?
该程序将在每个星期一早上运行,以提醒管理人员即将到来的生日,因此它可能跨越新的一年。
感谢Kogus,这是我最终创建的有效解决方案。
SELECT * FROM Employees WHERE Cast(DATEDIFF(dd, birthdt, getDate()) / 365.25 as int) - Cast(DATEDIFF(dd, birthdt, futureDate) / 365.25 as int) <> 0
解决方案
回答
我们可以使用DATE_FORMAT提取生日日期的日期和月份部分。
编辑:对不起,我没有看到他没有使用MySQL。
回答
更好的做法是,在BIRTHDAY日期加上年份之间的差值,以完成今年的所有工作,然后进行比较
SELECT * FROM Employees WHERE DATEADD ( year, YEAR(@Today) - YEAR(@Birthday), birthday) BETWEEN @Today AND @EndDate
回答
我们可以使用" DAYOFYEAR"功能,但要查找十二月的一月生日时要小心。只要我们要的日期范围不跨过新年,我认为我们就可以了。
回答
假设这是T-SQL,请使用DATEPART分别比较月份和日期。
http://msdn.microsoft.com/en-us/library/ms174420.aspx
或者,从每个人的生日中减去当前年份的1月1日,然后使用1900年(或者纪元年份)进行比较。
回答
这些解决方案中的大多数都很接近,但是我们必须记住一些其他方案。在处理生日和缩放比例时,我们必须能够处理到下个月的过渡。
例如,斯蒂芬斯(Stephens)示例非常适合生日,直到一个月的最后4天为止。然后,如果今天是29日,则存在逻辑错误,因为有效日期将是:29、30,然后是下一个月的1、2、3,因此我们也必须对此进行限制。
一种替代方法是从生日字段中解析日期,然后在当前年份中细分,然后进行标准范围比较。
回答
另一个想法是:将他们的整个年龄加到他们的生日中(如果还没有生日,则再增加一个,然后像上面一样进行比较。请使用DATEPART和DATEADD进行此操作。
http://msdn.microsoft.com/en-us/library/ms186819.aspx
跨年范围的边缘情况必须具有特殊代码。
温馨提示:考虑使用BETWEEN ... AND而不是重复Birthday操作数。
回答
对不起,没有看到中和这一年的要求。
select * from Employees where DATEADD (year, DatePart(year, getdate()) - DatePart(year, Birthday), Birthday) between convert(datetime, getdate(), 101) and convert(datetime, DateAdd(day, 5, getdate()), 101)
这应该工作。
回答
这应该工作...
DECLARE @endDate DATETIME DECLARE @today DATETIME SELECT @endDate = getDate()+6, @today = getDate() SELECT * FROM Employees WHERE (DATEPART (month, birthday) >= DATEPART (month, @today) AND DATEPART (day, birthday) >= DATEPART (day, @today)) AND (DATEPART (month, birthday) < DATEPART (month, @endDate) AND DATEPART (day, birthday) < DATEPART (day, @endDate))
回答
注意:我已经对其进行了编辑,以修复我认为是重要的错误。当前发布的版本适用于我。
在修改字段和表名称以使其与数据库相对应后,此方法应该起作用。
SELECT BRTHDATE AS BIRTHDAY ,FLOOR(DATEDIFF(dd,EMP.BRTHDATE,GETDATE()) / 365.25) AS AGE_NOW ,FLOOR(DATEDIFF(dd,EMP.BRTHDATE,GETDATE()+7) / 365.25) AS AGE_ONE_WEEK_FROM_NOW FROM "Database name".dbo.EMPLOYEES EMP WHERE 1 = (FLOOR(DATEDIFF(dd,EMP.BRTHDATE,GETDATE()+7) / 365.25)) - (FLOOR(DATEDIFF(dd,EMP.BRTHDATE,GETDATE()) / 365.25))
基本上,它是从生日到现在的日子,然后将其除以365(以避免舍入直接转换为年份时出现的问题)。
然后是从生日到现在的一周之间的日子,然后将其除以365,从现在开始一周。
如果他们的生日在一周之内,则这两个值之间的差将为1. 因此,它将返回所有这些记录。
回答
几年前,我在大学项目中遇到了同样的问题。我通过将年份和日期(MM:DD)分为两个单独的列来做出响应(以一种相当狡猾的方式)。在此之前,我的项目伙伴只是获取所有日期并以编程方式遍历它们。我们更改了它的原因是效率太低,也不是我的解决方案也没有那么优雅。另外,在多个应用程序已经使用了一段时间的数据库中,可能无法做到这一点。
回答
试试看:
SELECT * FROM Employees WHERE DATEADD(yyyy, DATEPART(yyyy, @Today)-DATEPART(yyyy, Birthday), Birthday) > @Today AND DATEADD(yyyy, DATEPART(yyyy, @Today)-DATEPART(yyyy, Birthday), Birthday) < DATEADD(dd, @NumDays, @Today)
回答
最好使用datediff和dateadd。没有四舍五入,没有近似值,没有2月29日的bug,仅是日期函数
ageOfThePerson = DATEDIFF(yyyy,dateOfBirth,GETDATE())
dateOfNextBirthday = DATEADD(yyyy,ageOfThePerson + 1,dateOfBirth)
daysBeforeBirthday = DATEDIFF(d,GETDATE(),dateofNextBirthday)
感谢@Gustavo Cardoso,此人的年龄有了新定义
ageOfThePerson = FLOOR(DATEDIFF(d,dateOfBirth,GETDATE())/ 365.25)
回答
坚果!在我开始考虑这个问题和回来回答之间一个很好的解决方案。 :)
我想出了:
select (365 + datediff(d,getdate(),cast(cast(datepart(yy,getdate()) as varchar(4)) + '-' + cast(datepart(m,birthdt) as varchar(2)) + '-' + cast(datepart(d,birthdt) as varchar(2)) as datetime))) % 365 from employees where (365 + datediff(d,getdate(),cast(cast(datepart(yy,getdate()) as varchar(4)) + '-' + cast(datepart(m,birthdt) as varchar(2)) + '-' + cast(datepart(d,birthdt) as varchar(2)) as datetime))) % 365 < @NumDays
我们不需要将getdate()转换为日期时间,对吗?
回答
员工Sqlserver即将到来的生日
DECLARE @sam TABLE ( EmployeeIDs int, dob datetime ) INSERT INTO @sam (dob, EmployeeIDs) SELECT DOBirth, EmployeeID FROM Employee SELECT * FROM ( SELECT *, bd_this_year = DATEADD(YEAR, DATEPART(YEAR, GETDATE()) - DATEPART(YEAR, dob), dob) FROM @sam s ) d WHERE d.bd_this_year > DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) AND d.bd_this_year <= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 3)
回答
我希望这可以在某种程度上对我们有所帮助。
select Employeename,DOB from Employeemaster where day(Dob)>day(getdate()) and month(DOB)>=month(getDate())
回答
这是已测试的几个答案的组合。这将在特定日期及其年龄之后的下一个生日。 numdays也将限制我们要查找的范围7天=周等。
SELECT DISTINCT FLOOR(DATEDIFF(dd,Birthday, @BeginDate) / 365.25) + 1 age, DATEADD(yyyy, FLOOR(DATEDIFF(dd,Birthday, @BeginDate) / 365.25) + 1, Birthday) nextbirthday, birthday FROM table WHERE DATEADD(yyyy, FLOOR(DATEDIFF(dd,Birthday, @BeginDate) / 365.25) + 1, Birthday) > @BeginDate AND DATEADD(yyyy, FLOOR(DATEDIFF(dd,Birthday, @BeginDate) / 365.25) + 1, Birthday) < DATEADD(dd, @NumDays, @BeginDate) order by nextbirthday
回答
达到相同目的的最佳方法是
DECLARE @StartDate DATETIME DECLARE @EndDate DATETIME SELECT Member.* from vwMember AS Member WHERE (DATEADD(YEAR, (DATEPART(YEAR, @StartDate) - DATEPART(YEAR, Member.dBirthDay)), Member.dBirthDay) BETWEEN @StartDate AND @EndDate)
回答
这是MS SQL Server的解决方案:
它会在30天内为员工送去生日。
SELECT * FROM rojstni_dnevi WHERE (DATEDIFF (dd, getdate(), DATEADD ( yyyy, DATEDIFF(yyyy, rDan, getdate()), rDan) nex ) +365) % 365 < 30
回答
尝试我的解决方案...我有Informix数据库...
SELECT person, year(today)-year(birthdate) as years, birthdate, CASE WHEN MOD(year(birthdate)+((year(today)-year(birthdate))+1),4)<>0 AND MONTH(birthdate)=2 AND DAY(birthdate)=29 THEN CASE WHEN mdy(month(birthdate), 28, year(birthdate)+((year(today)-year(birthdate))+1))-today >= 365 THEN (mdy(month(birthdate), 28, year(birthdate)+((year(today)-year(birthdate))+1))-today)-365 WHEN mdy(month(birthdate), 28, year(birthdate)+((year(today)-year(birthdate))+1))-today < 365 THEN mdy(month(birthdate), 28, year(birthdate)+((year(today)-year(birthdate))+1))-today END ELSE CASE WHEN mdy(month(birthdate), day(birthdate), year(birthdate)+((year(today)-year(birthdate))+1))-today >= 365 THEN (mdy(month(birthdate), day(birthdate), year(birthdate)+((year(today)-year(birthdate))+1))-today)-365 WHEN mdy(month(birthdate), day(birthdate), year(birthdate)+((year(today)-year(birthdate))+1))-today < 365 THEN mdy(month(birthdate), day(birthdate), year(birthdate)+((year(today)-year(birthdate))+1))-today END END until FROM table_name WHERE mdy(month(birthdate), day(birthdate), 2000) >= mdy(month(today), day(today), 2000) AND mdy(month(birthdate), day(birthdate), 2000) <= mdy(month(today), day(today), 2000)+30 OR mdy(month(birthdate), day(birthdate), 2000) <= mdy(month(today), day(today), 2000)-(365-30) ORDER BY 4, YEAR(birthdate)