Tage bis zum nächsten Geburtstag (datediff)

Mike34

Benutzer
Beiträge
6
Hallo,

in meiner Umschulung habe ich vor kurzem mit MySql begonnen und nun geht es darum, die Tage bis zum nächsten Geburtstag zu berechnen. Ich kenne auch einige Lösungen, nur verstehe ich sie teilweise nicht. Hier soll es speziell um DATEDIFF gehen.

Also die Lösung, die wir bekommen haben ist:

select datediff(date(concat(year(now()), '-', month(Person.Geburtsdatum), '-', day(Person.Geburtsdatum))), now()) from Person;

Was ich bisher verstanden habe:
Bei datediff schreibt man die beiden Daten in die Klammer und das war´s soweit.

Das Problem hier: Das erste Datum ist ja zusammengesetzt aus dem aktuellen Jahr, dem Monat aus der Tabelle und ebenso dem Tag. Ich verstehe nicht warum man hier zusätzlich noch date und concat benötigt. Und warum diese '-' ?

Meine Lösungsansatz wäre gewesen:

select datediff((year(now()), month(person.geburtsdatum),day(person.geburtsdatum)), now()) from person;

Allerdings funktioniert das so leider nicht.

Vielleicht kann mir hier jemand einen Denkanstoß geben. Ich glaube ich habe (uA) die Syntax noch nicht richtig verstanden.

Vielen Dank an alle, die sich die Mühe machen zu antworten!
 
Werbung:
weil Du ein valides Datum konstruieren mußt, um die Differenz zweier Tage zu ermitteln. Außerdem mußt du noch beachten, ob der geburtstag in diesem Jahr schon war. Hier ein unvollständiger Ansatz, die Vervollständigung überlasse ich Dir zur Übung.

Code:
edb=*# select * from person;
 name |      geb_datum     
------+---------------------
 a    | 1988-08-30 00:00:00
 b    | 2007-07-28 00:00:00
 c    | 2005-03-28 00:00:00
(3 rows)

edb=*# select *, case when extract(doy from geb_datum) > extract(doy from current_date) then (extract(year from current_date) || '-' || extract(month from geb_datum) || '-' || extract(day from geb_datum))::date - current_date end as tage from person;
 name |      geb_datum      |   tage   
------+---------------------+----------
 a    | 1988-08-30 00:00:00 | 108 days
 b    | 2007-07-28 00:00:00 | 75 days
 c    | 2005-03-28 00:00:00 |
(3 rows)

edb=*#
 
Hallo und danke für die schnelle Antwort. Diese Seite hatte ich schon gelesen und leider hat mir das nicht weitergeholfen. Vielleicht habe ich mein Problem auch nicht genau genug beschrieben. Also:

Der Gedanke war, dass man das aktuelle Datum (also now()) mit einem Datum aus der Tabelle vergleicht. Allerdings soll bei dem Datum aus der Tabelle die Jahrezahl durch das Jahr von now() ersetzt werden.

Bei datediff schreibt man ja nur zwei Daten in die Klammer, getrennt durch ein Komma.

Wie oben beschrieben habe ich für das erste Datum allerdings einen recht langen Ausdruck, getrennt durch mehrere Kommata und so funktioniert es auch nicht.
Also das erste Datum wäre dann:

year(now()), month(person.geburtsdatum),day(person.geburtsdatum)

das zweite:

now()

Wenn ich das so nach datediff in die Klammer schreibe, geht das halt nicht. Es wäre aber für mein Verständnis logisch und die Lösung, die wir bekommen haben mit concat und date versteh ich momentan echt nicht.
 
Bitte lies in der Doku nach, was die Funktionen wie year(now()) etc. liefern. Bitte überlge Dir, was dann year(now()),month(now()), ... dir liefert. Prüfe, was datediff() als Eingabeparameter erwartet. Vergleiche dies & finde Deinen Fehler.
 
Ebenfalls danke für deine Antwort akretschmer. Das stimmt, dass man schauen muss ob der Geburtstag schon war oder nicht. Allerdings hätte mir für den Augenblick auch diese unvollständige Lösung genügt. Also dass man ruhig auch negative Werte bekommen kann. Das wäre ja eine weiterführende Frage. Bei mir haperts ja schon bei date und concat.
Den Rest, den du beschreibst, hatten wir auch noch nicht, also case, extract, then. Wie gesagt leuchtet es mir auch nicht ein warum man hier überhaupt date benutzen muss, ebenso concat. Ich hätte einfach eine weitere Klammer um den ersten Teil des zusammengesetzten Datums gemacht (also nach datediff), aber so scheint das in MySql wohl nicht zu funktionieren.
 
vielleicht noch als nachträgliche Spielerei zur Veranschalichung:

Code:
edb=*# select extract(year from current_date), extract(month from current_date), extract(day from current_date), pg_typeof(extract(day from current_date));
 date_part | date_part | date_part |    pg_typeof     
-----------+-----------+-----------+------------------
      2021 |         5 |        14 | double precision
(1 row)

Die ersten 3 Spalten sind also das zerlegte heutige Datum, vom typ 'double precision'. Wenn Du daraus wieder ein Datum basteln willst, brauchst Du das a) als text und b) immer ein '-' dazwischen. Eine Klammer drum herum zu setzen, wie Du es versuchst, führt nur zu:

Code:
edb=*# select (extract(year from current_date), extract(month from current_date), extract(day from current_date)), pg_typeof(extract(day from current_date));
     row     |    pg_typeof     
-------------+------------------
 (2021,5,14) | double precision
(1 row)

Du bekommst also einen sog. Record-Typen:

Code:
edb=*# select pg_typeof((extract(year from current_date), extract(month from current_date), extract(day from current_date))), pg_typeof(extract(day from current_date));
 pg_typeof |    pg_typeof     
-----------+------------------
 record    | double precision
(1 row)

edb=*#

also einen zusammengesetzten Datentypen aus 3 Double-Werten. datediff erwartet was anderes ...

Und nein, das ist PostgreSQL, kein MySQL...
 
Nochmal danke für deine Tipps akretschmer. Ich glaube ich komme langsam dahinter.. du hast das gut umschrieben.
Vermutlich ist es so, dass die einzelnen Teile (Jahr, Monat und Tag) durch diese '-' zu einem vollständigen Datum zusammengesetzt werden. Dass das allerdings über
date und concat so geht, find ich jetzt nicht so eingängig zu verstehen.
Ich werd das Mal zum besseren Verständnis ein wenig testen. Vielleicht komm ich wieder ein wenig weiter.
 
ich würde dir dem Umstieg auf PostgreSQL empfehlen. Deutlich besser, leistungsfähiger und mehr an dem, was man so allgemein unter SQL versteht. MySQL und deren Varianten sind eher Müll.
 
Guten Morgen!

Ich denke, ich hab´s jetzt verstanden! Also der Teil mit Extrahieren von Jahr, Monat und Tag war soweit klar. Dann bringt man dies durch concat in das richtige Datumsformat, weil datediff das so benötigt. Allerdings muss man noch über date() das Datum extrahieren, weil concat allein wohl nicht zu reichen scheint. Bitte korrigiert mich, falls etwas falsch sein sollte.

@akretschmer die Umschulung hat erst vor Kurzem begonnen, ebenso die Arbeit mit MySql. Bisher kann ich noch nicht einschätzen wie der spätere Arbeitsalltag als Anwendungsentwickler aussehen wird und wie sehr ich mit MySql oder dem von dir genannten Programm zu tun haben werde. Ich habe nur festgestellt, dass es Unterschiede in der Syntax zu geben scheint, aber wenn du meinst, dass MySql nicht so toll ist, werd ich mir Mal deine Alternative für die Zukunft merken. Du scheinst dich damit ja gut auszukennen.
 
Werbung:
Ich habe nur festgestellt, dass es Unterschiede in der Syntax zu geben scheint, aber wenn du meinst, dass MySql nicht so toll ist, werd ich mir Mal deine Alternative für die Zukunft merken. Du scheinst dich damit ja gut auszukennen.

MySQL macht viele Dinge falsch, z.T. bekommst Du echt falsche Resultate bei Abfragen, bei denen andere Datenbanken den Syntaxfehler erkennen - MySQL führt es aus und liefert Fehler. Als Lernsystem daher ungeeignet. Und für praktische Anwendungen weitestgehend auch. Und ja, ich verdiene mit Support für PostgreSQL mein Geld.
 
Zurück
Oben