Ich habe eine Tabelle mit Personen zusammen mit ihrem Geburtsdatum (derzeit ein nvarchar (25))
Wie kann ich das in ein Datum umwandeln und dann ihr Alter in Jahren berechnen?
Meine Daten sehen wie folgt aus
ID Name DOB
1 John 1992-01-09 00:00:00
2 Sally 1959-05-20 00:00:00
Ich würde gerne ... sehen:
ID Name AGE DOB
1 John 17 1992-01-09 00:00:00
2 Sally 50 1959-05-20 00:00:00
Antworten:
Es gibt Probleme mit Schaltjahr / -tagen und der folgenden Methode, siehe Update unten:
UPDATE hier sind einige genauere Methoden:
BESTE METHODE FÜR JAHRE INT
Sie können die oben ändern
10000
zu10000.0
und Dezimalzahlen bekommen, aber es wird nicht unter so genau wie die Methode.BESTE METHODE FÜR JAHRE IM DEZIMAL
quelle
GETDATE()
am '2013-07-04 23:59:59' ausführen würde (anstelle von ' andere Variable verwenden '), heißt es, dass ich Ich bin 27, während ich in diesem Moment noch nicht bin. Beispielcode:declare @startDate nvarchar(100) = '1986-07-05 00:00:00' declare @endDate nvarchar(100) = '2013-07-04 23:59:59' SELECT DATEDIFF(hour,@startDate,@endDate)/8766.0 AS AgeYearsDecimal ,CONVERT(int,ROUND(DATEDIFF(hour,@startDate,@endDate)/8766.0,0)) AS AgeYearsIntRound ,DATEDIFF(hour,@startDate,@endDate)/8766 AS AgeYearsIntTrunc
select datediff(year, '2000-01-05', '2018-01-04')
18 zurück, nicht 17, wie es sollte. Ich habe das obige Beispiel unter der Überschrift "BESTE METHODE FÜR JAHRE IN INT" verwendet und es funktioniert perfekt. Vielen Dank!Ich muss diesen da rauswerfen. Wenn Sie konvertieren das Datum im Stil 112 (JJJJMMTT) in eine Zahl , können Sie eine Berechnung wie diese verwenden ...
(yyyyMMdd - yyyyMMdd) / 10000 = Differenz in vollen Jahren
Ausgabe
quelle
code: SELECT [Age] = (0+ FORMAT(@as_of,'yyyyMMdd') - FORMAT(@bday,'yyyyMMdd') ) /10000 --The 0+ part tells SQL to calc the char(8) as numbers
Ich habe diese Abfrage fast 10 Jahre lang in unserem Produktionscode verwendet:
quelle
DATEDIFF(yy, @BirthDate, GETDATE()) - CASE WHEN (MONTH(@BirthDate) >= MONTH(GETDATE())) AND DAY(@BirthDate) > DAY(GETDATE()) THEN 1 ELSE 0 END
CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END
So viele der oben genannten Lösungen sind falsch. DateDiff (yy, @ Dob, @PassedDate) berücksichtigt nicht den Monat und den Tag beider Daten. Auch die Dartteile zu nehmen und zu vergleichen funktioniert nur, wenn sie richtig bestellt sind.
DER FOLGENDE CODE FUNKTIONIERT UND IST SEHR EINFACH:
quelle
0925
(oder925
) um. Das Gleiche gilt für das aktuelle Datum (wie es der 16. Dezember wird1216
) und prüft dann, ob der DoB-Integer-Wert bereits übergeben wurde. Um diese ganze Zahl zu erstellen, sollte der Monat mit 100 multipliziert werden.(CONVERT(int,CONVERT(char(8),@Now,112))-CONVERT(char(8),@Dob,112))/10000
Sie müssen die Art und Weise berücksichtigen, in der der datierte Befehl rundet.
Was ich von hier aus angepasst habe .
Beachten Sie, dass der 28. Februar als Geburtstag eines Sprunges für Nicht-Schaltjahre betrachtet wird, z. B. wird eine am 29. Februar 2020 geborene Person am 28. Februar 2021 anstelle des 01. März 2021 als 1 Jahr alt angesehen.
quelle
SELECT DATEDIFF(year, DOB, getdate()) + CASE WHEN (DATEADD(year,DATEDIFF(year, DOB, getdate()) , DOB) > getdate()) THEN - 1 ELSE 0 END)
BEARBEITEN: DIESE ANTWORT IST FEHLERHAFT. Ich lasse es hier als Warnung für jeden, der versucht ist, es zu verwenden
dayofyear
, mit einer weiteren Bearbeitung am Ende.Wenn Sie wie ich nicht durch Bruchteile dividieren möchten oder Rundungs- / Schaltjahrfehler riskieren möchten, begrüße ich den Kommentar von @Bacon Bits in einem Beitrag über https://stackoverflow.com/a/1572257/489865, in dem er sagt:
Er bietet dann an:
Es gibt hier einige Vorschläge zum Vergleichen von Monat und Tag (und einige verstehen es falsch, wenn sie das
OR
hier nicht richtig berücksichtigen!). Aber niemand hat angebotendayofyear
, was so einfach und viel kürzer erscheint. Ich biete:[Hinweis: Nirgendwo in SQL ist BOL / MSDN
DATEPART(dayofyear, ...)
tatsächlich dokumentiert! Ich verstehe es als eine Zahl im Bereich von 1 bis 366; am wichtigsten ist, dass es sich nicht nach Gebietsschema gemäßDATEPART(weekday, ...)
& ändertSET DATEFIRST
.]EDIT: Warum
dayofyear
geht schief : Als Benutzer @AeroX hat kommentiert, wenn die Geburt / Startdatum ist nach dem Februar in einem Schaltjahr nicht, das Alter erhöht wird einen Tag früher , wenn der Strom / -ende ein Schaltjahr ist, zum Beispiel'2015-05-26'
,'2016-05-25'
gibt eine Alter von 1, wenn es noch 0 sein sollte. Der Vergleichdayofyear
in verschiedenen Jahren ist eindeutig gefährlich. Also mitMONTH()
undDAY()
ist doch nötig.quelle
DayOfYear
Methode einen Tag früher in jedem Schaltjahr erhöht .dayofyear
, aber klar bearbeitet, um zu zeigen, warum sie schief geht. Ich hoffe das ist passend.Da es keine einfache Antwort gibt, die immer das richtige Alter angibt, habe ich mir Folgendes ausgedacht.
Dies ergibt die Jahresdifferenz zwischen dem Geburtsdatum und dem aktuellen Datum. Dann wird ein Jahr abgezogen, wenn das Geburtsdatum noch nicht verstrichen ist.
Immer genau - unabhängig von Schaltjahren oder der Nähe zum Geburtsdatum.
Das Beste von allem - keine Funktion.
quelle
quelle
Wie wäre es mit:
Würde das nicht all diese Probleme beim Runden, Abschneiden und Versetzen vermeiden?
quelle
'1986-07-05 00:00:00'
für DOB und'2013-07-04 23:59:59'
für die aktuelle Zeit nehmen.Ich glaube, das ist ähnlich wie bei anderen, die hier gepostet wurden ... aber diese Lösung funktionierte für die Schaltjahrbeispiele vom 29.02.1976 bis zum 01.03.2011 und auch für den Fall für das erste Jahr .. wie 07/04 / 2011 bis 07/03/2012, die zuletzt über die Schaltjahrlösung veröffentlicht wurden, funktionierte für diesen Anwendungsfall des ersten Jahres nicht.
Gefunden hier .
quelle
quelle
Quelle: http://beginsql.wordpress.com/2012/04/26/how-to-calculate-age-in-sql-server/
quelle
code: SELECT [Age] = (0+ FORMAT(@ToDate,'yyyyMMdd') - FORMAT(@DOB,'yyyyMMdd') ) /10000
Ich habe viel darüber nachgedacht und gesucht und ich habe 3 Lösungen, die
Hier sind Testwerte:
Lösung 1: Ich habe diesen Ansatz in einer js-Bibliothek gefunden. Es ist mein Favorit.
Es fügt dem DOB tatsächlich einen Unterschied in Jahren hinzu. Wenn es größer als das aktuelle Datum ist, wird ein Jahr abgezogen. Einfach richtig? Das einzige ist, dass sich der Unterschied in den Jahren hier verdoppelt.
Wenn Sie es jedoch nicht inline verwenden müssen, können Sie es folgendermaßen schreiben:
Lösung 2: Diese habe ich ursprünglich von @ bacon-bits kopiert. Es ist am einfachsten zu verstehen, aber ein bisschen lang.
Es berechnet im Grunde das Alter wie wir Menschen.
Lösung 3: Mein Freund hat es in Folgendes umgestaltet:
Dieser ist der kürzeste, aber am schwierigsten zu verstehen.
50
ist nur ein Gewicht, daher ist der Tagesunterschied nur wichtig, wenn die Monate gleich sind.SIGN
Die Funktion dient zum Transformieren eines beliebigen Werts in -1, 0 oder 1. SieCEILING(0.5 *
ist dieselbe wie,Math.max(0, value)
aber in SQL gibt es so etwas nicht.quelle
quelle
Hier gibt es viele 365,25 Antworten. Denken Sie daran, wie Schaltjahre definiert sind:
quelle
Wie wäre es damit:
quelle
Versuche dies
quelle
Versuchen Sie diese Lösung:
quelle
Dadurch werden die Probleme mit dem Geburtstag und der Rundung korrekt behandelt:
quelle
Ed Harpers Lösung ist die einfachste, die ich gefunden habe und die niemals die falsche Antwort zurückgibt, wenn der Monat und der Tag der beiden Daten 1 oder weniger Tage voneinander entfernt sind. Ich habe eine leichte Änderung vorgenommen, um mit dem negativen Alter umzugehen.
quelle
Die als richtig gekennzeichnete Antwort ist näher an der Genauigkeit, schlägt jedoch im folgenden Szenario fehl : Geburtsjahr ist Schaltjahr und Tag nach Februar
ODER
- Die folgende Lösung liefert genauere Ergebnisse.
Es funktionierte in fast allen Szenarien, unter Berücksichtigung des Schaltjahres, des Datums als 29. Februar usw.
Bitte korrigieren Sie mich, wenn diese Formel eine Lücke hat.
quelle
floor
.quelle
Hier ist, wie ich das Alter anhand eines Geburtsdatums und eines aktuellen Datums berechne.
quelle
quelle
month(compare) > month(dob)
ABERday(compare) < day(dob)
zselect dbo.AgeAtDate('2000-01-14', '2016-02-12')
.quelle
Was ist mit einer Lösung, die nur Datumsfunktionen enthält, keine Mathematik, keine Sorgen um das Schaltjahr?
quelle
Nach dem Ausprobieren vieler Methoden funktioniert dies 100% der Zeit mit der modernen MS SQL FORMAT-Funktion, anstatt in Stil 112 zu konvertieren. Beides würde funktionieren, aber dies ist der geringste Code.
Kann jemand eine Datumskombination finden, die nicht funktioniert? Ich glaube nicht, dass es einen gibt :)
quelle
Wir haben so etwas wie hier benutzt, aber dann das Durchschnittsalter genommen:
Beachten Sie, dass die RUNDE eher außen als innen ist. Dadurch kann die AVG genauer sein und wir runden nur einmal. Schneller machen.
quelle
quelle
quelle