SQL选择即将到来的生日

时间:2020-03-05 18:58:57  来源:igfitidea点击:

我正在尝试编写一个存储过程来选择生日即将到来的员工。

从员工的生日中选择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)