2016-05-06 11 views
6

dieses Schema in einer Postgres Datenbank Gegeben:Wie berechnet man den nächsten Geburtstag bei einem Geburtsdatum?

CREATE TABLE person (
    id serial PRIMARY KEY, 
    name text, 
    birth_date date, 
); 

Wie würde ich die Tabelle abfragen, um den Tag der jeder Person nächsten Geburtstag nach dem heutigen Tag zu bekommen?

Zum Beispiel, wenn Bobs birth_date ist 2000-06-01 dann wäre sein nächster Geburtstag 2016-06-01.

Hinweis: Ich bin nicht auf der Suche nach der birth_date + eine vordefinierte interval sondern eher der nächste Jahrestag der Geburt einer Person.

ich das Äquivalent in Python geschrieben haben:

def next_birthday(self): 
    today = datetime.date.today() 
    next_birthday = self.birth_date.replace(year=today.year) 
    if next_birthday < today: 
     next_birthday = next_birthday.replace(year=today.year + 1) 
    return next_birthday 

Allerdings Ich mag würde, um zu sehen, ob Postgres dies in einer leistungsfähigere Art und Weise tun.

+0

@PetrHejda - diese Antwort wählt Geburtstage in einem bestimmten Zeitraum (1 Woche von heute). Ich freue mich darauf, den nächsten Geburtstag jedes Menschen zu feiern. – ghickman

+0

@Shanimal - diese Antwort filtert Zeilen, während ich suche, den nächsten bevorstehenden Geburtstag für jede Person zu berechnen. – ghickman

+0

Was ist mit 29. Februar, was sollte es zurückgeben? Wenn es im nächsten Jahr keinen 29. Februar gibt, sollte es am 28. Februar, 1. März oder am 29. Februar zurückkommen? – Peter

Antwort

4
select birth_date, 
     cast(birth_date + ((extract(year from age(birth_date)) + 1) * interval '1' year) as date) as next_birthday 
from person 
where name = 'Bob' 

Der Ausdruck (extract(year from age(birth_date)) + 1) * interval '1' year berechnet das Alter beim nächsten Geburtstag in (komplett) Jahren. Wenn Sie das zum Geburtsdatum hinzufügen, erhalten Sie den nächsten Geburtstag.

Die Besetzung ist notwendig, um eine echte date zurück zu bekommen, weil date + interval gibt einen Zeitstempel zurück (einschließlich einer Zeit).

Wenn Sie die where Bedingung entfernen, erhalten Sie alle "nächsten" Geburtstage.

Sie können auch eine Liste der kommenden Geburtstage in z. die nächsten 30 Tage mit etwas wie das:

select next_birthday, 
     next_birthday - current_date as days_until_next 
from (
    select birth_date, 
     cast(birth_date + ((extract(year from age(birth_date)) + 1) * interval '1' year) as date) as next_birthday 
    from person 
) as upcoming 
where upcoming.next_birthday <= current_date + 30 
order by next_birthday; 
+0

Brilliant :) Wie würden Sie diese Abfrage erweitern/ändern, damit Sie nicht nur eine Liste der nächsten Geburtstage erhalten, sondern auch die Geburtstage in 2, 3, 4 .. Jahren? In diesem Fall würde ich 'LIMIT 50' machen .. danke im Voraus! –

-1

SELECT Datum Geburtsdatum + Intervall '1 Jahr' als nächster_Birthday von Person;

+0

Dies gibt nur den ersten Geburtstag der Person, aber ich merke, meine Frage ist in diesem Punkt mehrdeutig und wird aktualisiert! – ghickman

0
SELECT 
    birth_date 
    + 
    cast(
     date_part('year', current_date) 
     - 
     date_part('year', birth_date) 
     + 
     CASE 
      WHEN 
       date_part('month', birth_date) < 
         date_part('month', current_date) 
       OR (
        date_part('month', birth_date) = 
          date_part('month', current_date) 
        AND 
        date_part('day', birth_date) < 
          date_part('day', current_date) 
       ) 
      THEN 1 
      ELSE 0 
     END || ' year' as interval) 
FROM person; 
Verwandte Themen