28 Stimmen

SQL Select Kommende Geburtstage

Ich versuche, eine gespeicherte Prozedur zu schreiben, um Mitarbeiter auszuwählen, die bevorstehende Geburtstage haben.

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

Das wird nicht funktionieren, weil das Geburtsjahr Teil des Geburtstags ist. Wenn ich also am 18.09.1983 Geburtstag hatte, liegt das nicht zwischen dem 18.09.2008 und dem 25.09.2008.

Gibt es eine Möglichkeit, den Jahresanteil von Datumsfeldern zu ignorieren und nur Monat/Tage zu vergleichen?

Dies wird jeden Montagmorgen durchgeführt, um die Manager auf bevorstehende Geburtstage aufmerksam zu machen, so dass es möglicherweise den Jahreswechsel überspannen wird.

Hier ist die funktionierende Lösung, die ich schließlich erstellt 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

0voto

Esteban Brenes Punkte 1133

Versuchen Sie dies:

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)

0voto

Mostlyharmless Punkte 2275

Vor ein paar Jahren stand ich bei meinem Hochschulprojekt vor demselben Problem. Ich reagierte darauf (auf eine ziemlich schlampige Art und Weise), indem ich das Jahr und das Datum (MM:DD) in zwei separate Spalten aufteilte. Davor hat mein Projektpartner einfach alle Datumsangaben abgerufen und sie programmgesteuert durchgegangen. Wir haben das geändert, weil es zu ineffizient war - nicht dass meine Lösung eleganter gewesen wäre. Außerdem ist es wahrscheinlich nicht möglich, dies in einer Datenbank zu tun, die schon eine Weile von mehreren Anwendungen genutzt wird.

0voto

bastos.sergio Punkte 6546

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

0voto

Patrick Szalapski Punkte 7759

Ein weiterer Gedanke: Addieren Sie ihr Alter in ganzen Jahren zu ihrem Geburtstag (oder ein weiteres, wenn ihr Geburtstag noch nicht stattgefunden hat) und vergleichen Sie dann wie oben. Verwenden Sie dazu DATEPART und DATEADD.

http://msdn.microsoft.com/en-us/library/ms186819.aspx

Für den Grenzfall eines Bereichs, der sich über das ganze Jahr erstreckt, müsste ein spezieller Code verwendet werden.

Bonustipp: Erwägen Sie die Verwendung von BETWEEN...AND anstelle der Wiederholung des Geburtstagsoperanden.

0voto

Mitchel Sellers Punkte 60318

Die meisten dieser Lösungen liegen nahe beieinander, aber Sie müssen einige zusätzliche Szenarien bedenken. Wenn Sie mit Geburtstagen und einer gleitenden Skala arbeiten, müssen Sie in der Lage sein, den Übergang in den nächsten Monat zu bewältigen.

Stephens Beispiel funktioniert zum Beispiel gut für Geburtstage bis zu den letzten 4 Tagen des Monats. Dann haben Sie einen Logikfehler, wie die gültigen Daten, wenn heute war der 29. wäre: 29, 30, UND dann 1, 2, 3 des nächsten Monats, so dass Sie für die Bedingung als gut haben.

Eine Alternative wäre, das Datum aus dem Geburtstagsfeld zu analysieren und das aktuelle Jahr einzugeben und dann einen standardmäßigen Bereichsvergleich durchzuführen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X