23 votos

SQL Select Próximos Cumpleaños

Estoy tratando de escribir un procedimiento almacenado para seleccionar a los empleados que han cumpleaños que son próximas.

SELECT * FROM Employees WHERE Birthday > @Today AND Birthday < @Today + @NumDays

Esto no va a funcionar porque el año de nacimiento es parte de Cumpleaños, así que si el día de mi cumpleaños fue '09-18-1983' que no se caiga entre '09-18-2008' y '09-25-2008'.

Es allí una manera de ignorar la parte de año de los campos de fecha y basta con comparar mes/días?

Este se ejecutará cada lunes por la mañana para alertar a los directivos de los cumpleaños próximos, por lo que posiblemente tendrá una duración de años nuevos.

Aquí está la solución de trabajo que terminé creando, gracias Kogus.

SELECT * FROM Employees 
WHERE Cast(DATEDIFF(dd, birthdt, getDate()) / 365.25 as int)
    - Cast(DATEDIFF(dd, birthdt, futureDate) / 365.25 as int) 
<> 0

30voto

JosephStyons Puntos 21187

Nota: he editado para corregir lo que yo creo fue un error significativo. Actualmente publicado la versión que funciona para mí.

Esto debería funcionar después de modificar el campo de los nombres de tabla y de corresponder a la base de datos.

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

Básicamente, se obtiene el número de días de su cumpleaños, y lo divide por 365 (para evitar el redondeo de los problemas que surgen al convertir directamente a los años).

A continuación, se obtiene el número de días de su cumpleaños para una semana a partir de ahora, y lo divide por 365 para obtener su edad de una semana a partir de ahora.

Si su cumpleaños es dentro de una semana, entonces la diferencia entre esos dos valores será 1. Así que devuelve todos los registros.

12voto

andufo Puntos 2522

En caso de que alguien todavía está buscando una solución en MySQL (ligeramente diferentes comandos), aquí está la consulta:

SELECT
 name,birthday,
 FLOOR(DATEDIFF(DATE(NOW()),birthday) / 365.25) AS age_now,
 FLOOR(DATEDIFF(DATE_ADD(DATE(NOW()),INTERVAL 30 DAY),birthday) / 365.25) AS age_future

FROM user

WHERE 1 = (FLOOR(DATEDIFF(DATE_ADD(DATE(NOW()),INTERVAL 30 DAY),birthday) / 365.25)) - (FLOOR(DATEDIFF(DATE(NOW()),birthday) / 365.25))

ORDER BY MONTH(birthday),DAY(birthday)

8voto

Philippe Grondier Puntos 6697

Mejor uso de datediff y dateadd. Sin redondeo, no se aproxima, no hay 29 de febrero de error, nada, pero las funciones de fecha

  1. ageOfThePerson = DATEDIFF ("yyyy", dateOfBirth, GETDATE())
  2. dateOfNextBirthday = DATEADD(aaaa, ageOfThePerson + 1, dateOfBirth)
  3. daysBeforeBirthday = DATEDIFF(d, GETDATE(), dateofNextBirthday)

Gracias a @Gustavo Cardoso, la nueva definición de la edad de la persona

  1. ageOfThePerson = FLOOR(DATEDIFF(d,dateOfBirth, GETDATE())/365.25)

2voto

Nick Berardi Puntos 31361

Lo sentimos, no vea el requisito para neutralizar el año.

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)

Esto debería funcionar.

2voto

Jovial Puntos 21

He encontrado la solución para esto. Esto puede salvar a alguien de un tiempo precioso.

 select EmployeeID,DOB,dates.date  from emp_tb_eob_employeepersonal 
 cross join dbo.GetDays(Getdate(),Getdate()+7) as dates where weekofmonthnumber>0
 and month(dates.date)=month(DOB) and day(dates.date)=day(DOB)



GO
/****** Object:  UserDefinedFunction [dbo].[GetDays]    Script Date: 11/30/2011 13:19:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--SELECT [dbo].[GetDays] ('02/01/2011','02/28/2011')

ALTER FUNCTION [dbo].[GetDays](@startDate datetime, @endDate datetime)
RETURNS @retValue TABLE
(Days int ,Date datetime, WeekOfMonthNumber int, WeekOfMonthDescription varchar(10), DayName varchar(10))
AS
BEGIN
    DECLARE @nextDay int
    DECLARE @nextDate datetime 
    DECLARE @WeekOfMonthNum int 
    DECLARE @WeekOfMonthDes varchar(10) 
    DECLARE @DayName varchar(10) 
    SELECT @nextDate = @startDate, @WeekOfMonthNum = DATEDIFF(week, DATEADD(MONTH, DATEDIFF(MONTH,0,@startDate),0),@startDate) + 1, 
    @WeekOfMonthDes = CASE @WeekOfMonthNum 
        WHEN '1' THEN 'First' 
        WHEN '2' THEN 'Second' 
        WHEN '3' THEN 'Third' 
        WHEN '4' THEN 'Fourth' 
        WHEN '5' THEN 'Fifth' 
        WHEN '6' THEN 'Sixth' 
        END, 
    @DayName 
    = DATENAME(weekday, @startDate)
SET @nextDay=1
WHILE @nextDate <= @endDate 
BEGIN 
    INSERT INTO @retValue values (@nextDay,@nextDate, @WeekOfMonthNum, @WeekOfMonthDes, @DayName) 
    SELECT @nextDay=@nextDay + 1 
SELECT @nextDate = DATEADD(day,1,@nextDate), 
    @WeekOfMonthNum 
    = DATEDIFF(week, DATEADD(MONTH, DATEDIFF(MONTH,0, @nextDate),0), @nextDate) + 1, 
    @WeekOfMonthDes 
    = CASE @WeekOfMonthNum 
    WHEN '1' THEN 'First' 
    WHEN '2' THEN 'Second' 
    WHEN '3' THEN 'Third' 
    WHEN '4' THEN 'Fourth' 
    WHEN '5' THEN 'Fifth' 
    WHEN '6' THEN 'Sixth' 
    END, 
    @DayName 
    = DATENAME(weekday, @nextDate) 
    CONTINUE 
END 

WHILE(@nextDay <=31)
BEGIN


    INSERT INTO @retValue values (@nextDay,@nextDate, 0, '', '') 
    SELECT @nextDay=@nextDay + 1

END

    RETURN
END

Hacer una cruz unirse con las fechas y verificación para la comparación de mes y las fechas.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X