it-swarm-eu.dev

SQL Wählen Sie Anstehende Geburtstage aus

Ich versuche, eine gespeicherte Prozedur zu schreiben, um Mitarbeiter auszuwählen, deren Geburtstage bevorstehen. 

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

Dies wird nicht funktionieren, da das Geburtsjahr Teil des Geburtstages ist. Wenn mein Geburtstag also "09 -18-1983" war, liegt das nicht zwischen "09 -18-2008" und "09 -25-2008". 

Gibt es eine Möglichkeit, den Jahresanteil der Datumsfelder zu ignorieren und nur den Monat/die Tage zu vergleichen? 

Dies wird jeden Montagmorgen ausgeführt, um die Manager auf bevorstehende Geburtstage aufmerksam zu machen, so dass sich möglicherweise neue Jahre erstrecken werden. 

Hier ist die funktionierende Lösung, die ich am Ende geschaffen habe, danke Kogus. 

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

Hinweis: Ich habe das so bearbeitet, dass ein meiner Meinung nach bedeutender Fehler behoben wurde. Die aktuell veröffentlichte Version funktioniert für mich.

Dies sollte funktionieren, nachdem Sie die Feld- und Tabellennamen so geändert haben, dass sie Ihrer Datenbank entsprechen.

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

Im Grunde erhält es die Anzahl der Tage von ihrem Geburtstag bis heute und teilt sie durch 365 (um Rundungsprobleme zu vermeiden, die entstehen, wenn Sie direkt in Jahre konvertieren).

Dann erhält es die Anzahl der Tage von ihrem Geburtstag bis zu einer Woche und teilt diese Zahl mit 365, um in einer Woche ihr Alter zu erhalten.

Wenn ihr Geburtstag innerhalb einer Woche liegt, ist der Unterschied zwischen diesen beiden Werten 1. Daher werden alle diese Datensätze zurückgegeben.

30
JosephStyons

Falls noch jemand nach einer Lösung in MySQL sucht (etwas andere Befehle), ist hier die Abfrage:

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)
12
Andres SK

Beste Verwendung von Datediff und Dateadd. Keine Rundung, keine Annäherung, kein 29. Februar-Fehler, nichts als Datumsfunktionen

  1. ageOfThePerson = DATEDIFF(yyyy,dateOfBirth, GETDATE())

  2. dateOfNextBirthday = DATEADD(yyyy,ageOfThePerson + 1, dateOfBirth)

  3. daysBeforeBirthday = DATEDIFF(d,GETDATE(), dateofNextBirthday)

Danke an @Gustavo Cardoso, neue Definition für das Alter der Person

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

Mochte die Annäherung von @strelc, aber sein SQL war ein bisschen abgenutzt. Hier ist eine aktualisierte Version, die gut funktioniert und einfach zu bedienen ist:

SELECT * FROM User 
WHERE (DATEDIFF(dd, getdate(), DATEADD(yyyy, 
    DATEDIFF(yyyy, birthdate, getdate()) + 1, birthdate)) + 1) % 366 <= <number of days>

edit 10/2017: addiere einen Tag zum Ende

3
Edyn

Ich habe die Lösung dafür gefunden. Dies kann jemandem wertvolle Zeit sparen.

 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 @[email protected] + 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 @[email protected] + 1

END

    RETURN
END

Machen Sie einen Cross-Join mit den Datumsangaben und prüfen Sie, ob der Monat und das Datum verglichen werden.

2
Jovial

Sie können die Funktion DAYOFYEAR verwenden. Seien Sie jedoch vorsichtig, wenn Sie im Dezember nach Geburtstagen für Januar suchen möchten. Ich denke, dass es Ihnen gut gehen wird, solange der Datumsbereich, den Sie suchen, nicht das neue Jahr umfasst.

2
Dave Webb

Meine Vermutung, "365.25" zu verwenden, würde bald oder später fehlschlagen.

Also teste ich die Arbeitslösung mit "365.25" Und gibt nicht für jeden Fall die gleiche Anzahl von Zeilen zurück. Hier ein Beispiel:

http://sqlfiddle.com/#!3/94c3ce/7

testen Sie mit Jahr 2016 und 2116 und Sie werden den Unterschied sehen. Ich kann nur einen Link posten, aber de/7 um/8 ändern, um beide Abfragen anzuzeigen. (/ 10 und/11 für die erste Antwort)

Ich schlage also eine andere Frage vor, bei der der nächste Geburtstag ab einem Startdatum bestimmt wird, und vergleicht dann, ob er in meinem Interessensbereich liegt.

SELECT * FROM Employees 
WHERE 
CASE WHEN (DATEADD(yyyy,DATEDIFF(yyyy, birthdt, @fromDate),birthdt) < @fromDate )
THEN DATEADD(yyyy,DATEDIFF(yyyy, birthdt, @fromDate)+1,birthdt)
ELSE DATEADD(yyyy,DATEDIFF(yyyy, birthdt, @fromDate),birthdt) END
BETWEEN @fromDate AND @toDate
2
Fede H

Sorry hat die Anforderung, das Jahr zu neutralisieren, nicht gesehen.

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)

Das sollte funktionieren.

2
Nick Berardi

In weniger als einem Monat:

SELECT * FROM people WHERE MOD( DATEDIFF( CURDATE( ) , `date_birth`) /30, 12 ) <1 and (((month(`date_birth`)) = (month(curdate())) and (day(`date_birth`)) > (day (curdate() ))) or ((month(`date_birth`)) > (month(curdate())) and (day(`date_birth`)) < (day (curdate() ))))
1
Danilo

Dies ist eine Lösung für MS SQL Server: Es werden Mitarbeiter mit Geburtstagen in 30 Tagen zurückgegeben.

SELECT * FROM rojstni_dnevi
  WHERE (DATEDIFF   (dd, 
                    getdate(), 
                    DATEADD (   yyyy, 
                                DATEDIFF(yyyy, rDan, getdate()),
                                rDan)
    nex             )
        +365) % 365 < 30
1
strelc

Ich habe dies für MySQL verwendet, wahrscheinlich nicht die effizienteste Art der Abfrage, aber einfach zu implementieren. 

select * from `schema`.`table` where date_format(birthday,'%m%d') >= date_format(now(),'%m%d') and date_format(birthday,'%m%d') < date_format(DATE_ADD(NOW(), INTERVAL 5 DAY),'%m%d');
0
Xocoatzin

Sie können auch DATEPART verwenden:

-- To find out Today's Birthday
DECLARE @today DATETIME
SELECT  @today = getdate()

SELECT *
FROM SMIS_Registration 
WHERE (DATEPART (month, DOB) >= DATEPART (month, @today)
      AND DATEPART (day, DOB) = DATEPART (day, @today))
0
Raj Sharma

Diese Lösung berücksichtigt auch Geburtstage im nächsten Jahr und die Reihenfolge: (Dob = Geburtstag; bty = Geburtstag in diesem Jahr; nbd = nächster Geburtstag)

with rs (bty) as (
    SELECT DATEADD(Year, DATEPART(Year, GETDATE()) - DATEPART(Year, dob), dob) as bty FROM Employees
),
rs2 (nbd) as (
  select case when bty < getdate() then DATEADD(yyyy, 1, bty) else bty end as nbd from rs
)
select nbd, DATEDIFF(d, getdate(), nbd) as diff from rs2 where DATEDIFF(d, getdate(), nbd) < 14 order by diff

Diese Version, die einen Vergleich der Daten vermeidet, könnte schneller sein:

with rs (dob, bty) as (
    SELECT dob, DATEADD(Year, DATEPART(Year, GETDATE()) - DATEPART(Year, DOB), DOB) as bty FROM employee
),
rs2 (dob, nbd) as (
  select dob,  DATEADD(yyyy, FLOOR(ABS((-1*(SIGN(DATEDIFF(d, getdate(), bty))))+0.1)), bty) as nbd from rs
),
rs3 (dob, diff) as (
  select dob, datediff(d, getdate(), nbd) as diff from rs2
)
select dob, diff  from rs3 where diff < 14 order by diff

Wenn der Bereich den 29. Februar des nächsten Jahres abdeckt, verwenden Sie:

with rs (dob, ydiff) as (
  select dob, DATEPART(Year, GETDATE()) - DATEPART(Year, DOB) as ydiff from Employee
),
rs2 (dob, bty, ydiff) as (
  select dob, DATEADD(Year, ydiff, dob) as bty, ydiff from rs
),
rs3 (dob, nbd) as (
  select dob, DATEADD(yyyy, FLOOR(ABS((-1*(SIGN(DATEDIFF(d, getdate(), bty))))+0.1)) +  ydiff, dob) as nbd from rs2
),
rs4 (dob, ddiff, nbd) as (
  select dob, datediff(d, getdate(), nbd) as diff, nbd from rs3
)
select dob, nbd, ddiff from rs4 where ddiff < 68 order by ddiff
0
Pilso

Bessere und einfache Lösung:

select * from users with(nolock)
where date_of_birth is not null 
and 
(
      DATEDIFF(dd,
                  DATEADD(yy, -(YEAR(GETDATE())-1900),GETDATE()), --Today
                  DATEADD(yy, -(YEAR(date_of_birth)-1901),date_of_birth)
      ) % 365
) = 30
0
AjitChahal

geburtsdatum auswählen, Name von Mitarbeitern Reihenfolge nach Fall WHEN convert (nvarchar (5), BirthDate, 101)> convert (nvarchar (5), GETDATE (), 101), dann 2 WHEN convert (nvarchar (5), BirthDate, 101) <convert (nvarchar (5), GETDATE (), 101), dann 3 WHEN convert (nvarchar (5), BirthDate, 101) = convert ( nvarchar (5), GETDATE (), 101) dann 1 sonst 4 Ende, konvertieren (nvarchar (2), Geburtsdatum, 101), konvertieren (nvarchar (2), Geburtsdatum, 105)

0

Aktuelle Monate Geburtstag

SELECT * FROM tblMember m
WHERE m.GDExpireDate != '' 
AND CONVERT(CHAR(2),CONVERT(datetime, m.dob, 103), 101) = CONVERT(CHAR(2), GETDATE(), 101)    
AND CONVERT(CHAR(2),CONVERT(datetime, m.dob, 103), 103) >= CONVERT(CHAR(2), GETDATE(), 103)
0
Bhavesh Patel

Nüsse! Eine gute Lösung zwischen dem Zeitpunkt, als ich anfing, darüber nachzudenken, und wann ich zur Antwort zurückkam. :)

Ich hatte die Idee dass:

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

Sie müssen getdate () nicht als Datumszeit verwenden, oder?

0
clweeks

Sie können DATE_FORMAT verwenden, um die Tages- und Monatsteile der Geburtstage zu extrahieren.

EDIT: Entschuldigung, ich habe nicht gesehen, dass er MySQL nicht benutzt hat.

0
p4bl0

Der beste Weg, das gleiche zu erreichen, ist

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)
0
Ramandeep Singh

Ich hatte vor einigen Jahren mit meinem College-Projekt das gleiche Problem. Ich antwortete (ziemlich wieselig), indem ich Jahr und Datum (MM: DD) in zwei getrennte Spalten aufteilte. Und vorher hatte mein Projektkamerad einfach alle Termine erhalten und sie programmatisch durchlaufen. Wir haben das geändert, weil es zu ineffizient war - auch nicht, dass meine Lösung eleganter war. In einer Datenbank, die seit einiger Zeit von mehreren Apps verwendet wird, ist dies wahrscheinlich nicht möglich.

0
Mostlyharmless

Dies ist eine Kombination aus einigen Antworten, die getestet wurden. Dies wird den nächsten Tag nach einem bestimmten Datum und dem Alter finden, das sie sein werden. Auch die Anzahl der Tage wird den Bereich einschränken, den Sie suchen, 7 Tage = Woche usw.

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

Lösung für SQLite:

SELECT
    *, 
    strftime('%j', birthday) - strftime('%j', 'now') AS days_remaining
FROM
    person
WHERE :n_days >= CASE
    WHEN days_remaining >= 0 THEN days_remaining
    ELSE days_remaining + strftime('%j', strftime('%Y-12-31', 'now'))
    END
;

Die Lösungen, die durch 325,25 geteilt wurden, um das Alter zu ermitteln oder das Geburtsdatum auf das aktuelle Jahr usw. zu bringen, haben bei mir nicht funktioniert. Dies berechnet das Delta der zwei Tage des Jahres (1-366). Wenn der Geburtstag in diesem Jahr noch nicht passiert ist, erhalten Sie automatisch die richtige Anzahl verbleibender Tage, mit denen Sie vergleichen können. Wenn der Geburtstag bereits passiert ist, ist "residual_days" negativ und Sie können die korrekte Anzahl verbleibender Tage ermitteln, indem Sie die Gesamtzahl der Tage im aktuellen Jahr addieren. Dies behandelt auch Schaltjahre korrekt, da in diesem Fall auch der zusätzliche Tag hinzugefügt wird (Mit dayOfYear (31. Dez.))

0
smoothware

ich glaube, dieses Ticket wurde schon vor langer Zeit geschlossen, aber um die richtige SQL-Abfrage zu erhalten, werfen Sie einen Blick darauf.

SELECT Employee_Name, DATE_OF_BIRTH
FROM Hr_table 
WHERE 

/**
fetching the original birth_date and replacing the birth year to the current but have to  deduct 7 days to adjust jan 1-7 birthdate.
**/

datediff(d,getdate(),DATEADD(year,datediff(year,DATEADD(d,-7,hr.DATE_OF_BIRTH),getdate()),hr.date_of_birth)) between 0 and 7

-- current date looks ahead to 7 days for upcoming modified year birth date.

order by

-- sort by no of days before the birthday
datediff(d,getdate(),DATEADD(year,datediff(year,DATEADD(d,-7,hr.DATE_OF_BIRTH),getdate()),hr.date_of_birth))
0
maSTAShuFu

Die folgende Abfrage gibt den nächsten Geburtstag des Mitarbeiters zurück. Dies ist die kürzeste Abfrage.

SELECT 
    Employee.DOB,
    DATEADD(
                mm, 
                (
                    (
                        (
                            (
                                DATEPART(yyyy, getdate())-DATEPART(yyyy, Employee.DOB )
                            )
                            +
                            (
                                1-
                                (
                                    ((DATEPART(mm, Employee.DOB)*100)+DATEPART(dd, Employee.DOB))
                                    /
                                    ((DATEPART(mm, getdate())*100) + DATEPART(dd, getdate()))
                                )
                            )
                        )
                    *12
                    )
                ), 
                Employee.DOB
            ) NextDOB
FROM 
    Employee 
ORDER BY 
    NextDOB ;

Die obige Abfrage gilt für den nächsten Monat mit Ausnahme des aktuellen Datums.

0
Paresh Patel

Angenommen, dies ist T-SQL, verwenden Sie DATEPART, um Monat und Datum separat zu vergleichen. 

http://msdn.Microsoft.com/de-de/library/ms174420.aspx

Alternativ können Sie den 1. Januar des aktuellen Jahres von jedem Geburtstag abziehen und dann das Jahr 1900 (oder was auch immer Ihr Epochenjahr ist) vergleichen.

0

Die meisten dieser Lösungen sind nahe, aber Sie müssen sich einige zusätzliche Szenarien merken. Wenn Sie mit Geburtstagen und einer gleitenden Skala arbeiten, müssen Sie den Übergang in den nächsten Monat bewältigen können. 

Zum Beispiel funktioniert Stephens Beispiel für Geburtstage bis zu den letzten 4 Tagen des Monats. Dann haben Sie einen logischen Fehler, da die gültigen Daten, wenn heute der 29. wäre, 29, 30 und dann 1, 2, 3 des NEXT-Monats wären, also müssen Sie auch dafür Konditionieren.

Eine Alternative wäre, das Datum aus dem Geburtstagsfeld und das aktuelle Jahr zu analysieren und dann einen Standardbereichsvergleich durchzuführen.

0
Mitchel Sellers

Ein weiterer Gedanke: Fügen Sie ihr Alter in ganzen Jahren zum Geburtstag hinzu (oder ein weiteres, wenn der Geburtstag noch nicht stattgefunden hat, und vergleichen Sie dann wie oben beschrieben. Verwenden Sie dazu DATEPART und DATEADD.).

http://msdn.Microsoft.com/de-de/library/ms186819.aspx

Der Edge-Fall eines Bereichs, der das Jahr umfasst, müsste besonderen Code haben.

Bonus-Tipp: Ziehen Sie die Verwendung von BETWEEN ... AND in Betracht, anstatt den Operanden Geburtstag zu wiederholen.

0

Probieren Sie es aus:

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)
0
Esteban Brenes

Das sollte funktionieren...

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))
0
bastos.sergio

Ich hoffe das hilft dir irgendwie ...

select Employeename,DOB 
from Employeemaster
where day(Dob)>day(getdate()) and month(DOB)>=month(getDate())
0
Bharathi

Anstehender Geburtstag für den Mitarbeiter - 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)
0
samdoss