Bedeutung der Anzahl der Tage im Durchschnittsalter?

7

Ich möchte das Durchschnittsalter meiner Benutzer kennen und habe dazu Folgendes getan:

# SELECT avg(age(birthday)) FROM "user";
                   avg
------------------------------------------
 33 years 10 mons 32 days 08:33:10.577946

Was bedeutet die Anzahl der Tage? Wie kann es über 31 Tage sein?

Ich habe 3746 Datensätze und bin in der UTC-Zeitzone.

PS: Ich benutze Postgres 9.5.3

n1r3
quelle
Befinden Sie sich in einer Zeitzone von mehr als 9 Stunden? Es ist das einzige, was ich mir vorstellen kann, das es zu einem (fehlerhaften) Präsentationsproblem gemacht hat.
Philᵀᴹ
2
Sie können justify_days()(oder justify_interval) verwenden, um das Intervall zu "normalisieren"
a_horse_with_no_name
1
Gibt SELECT age(avg(birthday)) FROM "user";das gleiche Ergebnis?
Ypercubeᵀᴹ
@ ypercubeᵀᴹ, das habe ich schon einmal versucht, aber es avg(birthday) gibt "Keine Funktion stimmt mit dem angegebenen Namen und den angegebenen Argumenttypen überein."
n1r3
@a_horse_with_no_name das macht den Trick! Vielen Dank. Gibt es einen Hinweis, warum dies nicht das Standardverhalten ist?
n1r3

Antworten:

1

age()gibt Intervalle zurück. In SQL-92 ist "an Intervaleine nicht verankerte Richtungsdauer der Zeitlinie" [1]. Sie haben zwei Typen aufgrund unterschiedlicher Monatslängen im Gregorianischen Kalender (Jahr zu Monat und Tag zu Sekunde). Oracle gibt eine Fehlermeldung aus, wenn Sie versuchen, das zu tun, was Sie getan haben . Intervalle können positiv und negativ sein. Sie müssen verankert sein, um eine genaue Bedeutung zu haben date + interval = date2. Wenn Sie Durchschnittswerte dieser Werte ermitteln, ist dies im Allgemeinen schlecht definiert. Wenn Sie sie auf Alterswerte prüfen, erhalten Sie möglicherweise immer noch unerwartete Ergebnisse (wie dies der Fall ist).

Was bedeutet a 3 month 32 daysin Postgres? Nun, nur der Code kann es mit Sicherheit sagen (oder derjenige, der es geschrieben hat). Ich denke, es bedeutet "einen Monat vorrücken, dann 32 Tage". Man kann Tage nicht in Monate umwandeln oder umgekehrt.

Wie kann es passieren, dort zu sein? Der Durchschnitt reagiert empfindlich auf Ausreißer. Wenn also tagelang ein ziemlich großer Wert vorhanden ist, hat dies einen Einfluss. Wie werden nullWerte behandelt? Haben einige Benutzer Daten für die Zukunft angegeben oder unangemessene Werte angegeben? Gibt es eine implizite Konvertierung? Haben Postgres-Entwickler eine spezielle Durchschnittsfunktion für Intervalle erstellt?

Für Ihr Problem empfehle ich die Verwendung (Entschuldigung, wenn dies nicht funktioniert, habe ich keine Datenbank zur Hand):

select avg(extract(epoch from now()) - extract(epoch from birthday)) from "user";

Dies funktioniert für Benutzer in einem angemessenen Alter. Wenn Sie jedoch Benutzer ab dem 18. Jahrhundert hatten, hängt die Antwort auch vom Standort ab, da der neue Kalender später in einigen Ländern übernommen wurde.

Lesen Sie das folgende Buch, um andere Macken mit Daten kennenzulernen.

[1] "Entwicklung zeitorientierter Datenbankanwendungen in SQL", Richard T. Snodgrass, Morgan-Kaufmann, 1999. Siehe seine Homepage , Seiten 30-32.

Grimaldi
quelle
extract(epoch FROM age(birthdate));klingt für mich besser.
Evan Carroll
Wenn Sie extract(epoch from '1 month')' the value is undefined. A one month delta can be 28, 29, 30 or 31 days. The semantics of age (t) verwenden, wird now()-teine korrekte Konvertierung zugelassen, aber jeder andere Referenzwert ist möglicherweise falsch. Das Delta auf der Ebene von Unix-Zeitstempeln zu nehmen, ermöglicht eine korrekte Verallgemeinerung (natürlich ohne Berücksichtigung von Schaltsekunden) und ist daher eine korrekte Verwendung im Produktionscode.
Grimaldi
0

Die Funktion AGE()gibt einen interval[1] -Wert zurück.

Wenn Sie nur die Jahre berechnen möchten, müssen Sie diese über die ageFunktion extrahieren , z.

SELECT AVG(EXTRACT(year FROM AGE(birthday))) FROM user;

Weitere Informationen finden Sie in der Dokumentation [2].

Verweise:

  1. https://www.postgresql.org/docs/current/static/datatype-datetime.html
  2. https://www.postgresql.org/docs/9.5/static/functions-datetime.html
Sebastian Webber
quelle
Die Mittelung der Anzahl der Jahre führt zu einem Präzisionsverlust, nicht wahr?
n1r3