Berechnen Sie das Alter in MySQL (InnoDb)

69

Wenn ich das Geburtsdatum einer Person in einer Tabelle im Formular gespeichert habe dd-mm-yyyyund es vom aktuellen Datum abziehe, in welchem ​​Format wird das Rückgabedatum angegeben?

Wie kann ich dieses zurückgegebene Format verwenden, um das Alter einer Person zu berechnen?

user559142
quelle
5
Wofür ist RDBMS? Datumsfunktionen sind nicht so gut standardisiert AFAIK. Und was meinst du im Format gespeichert dd-mm-yyyy? Wenn es sich um einen dateDatentyp handelt, wird es wahrscheinlich in einem numerischen Format gespeichert (z. B. als Ganzzahl mit Tagen seit einem Startpunkt)
Martin Smith,
Hallo, ich verwende InnoDb mit phpMyAdmin .... Es wird als Datumsvariable gespeichert. Ich denke, es ist yyyymmdd - Fehler oben gemacht
user559142
Wenn Daten als Datentyp DATE oder DATETIME gespeichert werden, werden sie als Binärwert gespeichert, NICHT in einem bestimmten für Menschen lesbaren Format. Die Formatierung erfolgt nur bei der Ausgabe in Text und hängt von Faktoren wie der Einstellung des Gebietsschemas des Betriebssystems oder den von Ihnen bereitgestellten expliziten Formatierungsanweisungen ab. Verarbeiten Sie nach Möglichkeit DATE- und DATETIME-Werte mit Funktionen, die Werte vom Typ DATE und DATETIME erwarten . Dann haben Sie keine Probleme mit dem Datumsformat. Möglicherweise müssen Sie sich noch mit der Zeitzone herumschlagen, aber zumindest ist Ihre Berechnung dann nur ein wenig falsch und nicht vollständig kaputt.
Gwideman

Antworten:

62

Wenn der Wert als Datentyp DATETIME gespeichert ist:

SELECT YEAR(CURRENT_TIMESTAMP) - YEAR(dob) - (RIGHT(CURRENT_TIMESTAMP, 5) < RIGHT(dob, 5)) as age 
  FROM YOUR_TABLE

Weniger genau, wenn man Schaltjahre betrachtet:

SELECT DATEDIFF(CURRENT_DATE, STR_TO_DATE(t.birthday, '%d-%m-%Y'))/365 AS ageInYears
  FROM YOUR_TABLE t 
OMG Ponys
quelle
... /365.25 für Schaltjahre. Im Jahr 2000 wurde das Schaltjahr jedoch übersprungen. Aber wenn Sie mit einem Fehler von 1 Tag leben können.
Benutzer unbekannt
38
Es gibt eine korrekte Antwort in der offiziellen MySQL-Dokumentation: dev.mysql.com/doc/refman/5.0/en/date-calculations.html
Mojuba
@mojuba: Das ist ein anderer Weg, nicht unbedingt richtig - ich glaube nicht, dass das OP dies als Antwort markiert hätte, wenn es nicht zufriedenstellend gewesen wäre. Ich würde es begrüßen, wenn Sie Ihre Ablehnung angesichts dessen rückgängig machen und die Frage fast zwei Jahre alt ist.
OMG Ponys
3
@OMG Ponys Es tut mir leid, aber eine Annahme, dass es 365 Tage im Jahr gibt, kann niemals zu einer korrekten Altersberechnung führen. Bei einer 40-jährigen Person geben Sie beispielsweise 10 Tage nach dem Geburtstag der Person ein falsches Alter an.
Mojuba
1
@OMG Ponys Nein, nein und nein. Der Fehler in Ihrer Formel ist ungefähr Alter / 4, da dies die Anzahl der Schaltjahre (dh die Anzahl der nicht berücksichtigten zusätzlichen Tage) in Ihrer Formel ist. Versuchen Sie dies zu überprüfen: timeanddate.com/date/duration.html
mojuba
246

Sie können folgende TIMESTAMPDIFF(unit, datetime_expr1, datetime_expr2)Funktion verwenden:

SELECT TIMESTAMPDIFF(YEAR, '1970-02-01', CURDATE()) AS age

Demo

Glavić
quelle
12
Kleine, präzise und einfache Lösung.
4
Dies scheint der klare Gewinner zu sein. Ich weiß nicht, warum sich jemand mit den komplizierten und
fehlerhaften
3
Beste Lösung, aber schwer zu finden am Ende dieser Seite.
Erik van de Ven
1
@ErikvandeVen bestellen Sie die Antworten durch Stimmen, nicht älteste
Leandro
10
select *,year(curdate())-year(dob) - (right(curdate(),5) < right(dob,5)) as age from your_table

Auf diese Weise berücksichtigen Sie sogar Monat und Tag der Geburt, um eine genauere Altersberechnung zu erhalten.

Nicola Cossu
quelle
Wow, das funktioniert großartig - kannst du mir erklären, was der Teil - (richtig (curdate (), 5) <richtig (dob, 5)) macht?
user559142
Ja. Rechts (..., 5) extrahiert mm-dd aus dem aktuellen Datum und dem Geburtsdatum. Sie vergleichen sie mit dem Symbol "<", das 0 zurückgibt, wenn Tag und Monat des Geburtsdatums unter dem aktuellen Datum liegen, andernfalls 1. Sie können es also (0 oder 1) von der Jahresdifferenz abziehen.
Nicola Cossu
1
Ich würde eine große Änderung vornehmen. Auf meinem MySQL-Recht (dob, 5) wird der Stunden-Minuten-Abschnitt des Datums zurückgegeben. Dies würde durch die Verwendung behoben year(curdate())-year(dob) - (dayofyear(curdate()) < dayofyear(dob)) as age, und ich finde, dass der Tag des Jahres eleganter ist.
Regilero
Und natürlich schlägt dies alles fehl, wenn dob zufällig als Datum / Uhrzeit gespeichert wird. Verwenden Sie einfach TIMESTAMPDIFF ()
gwideman
9
SELECT TIMESTAMPDIFF (YEAR, YOUR_COLUMN, CURDATE()) FROM YOUR_TABLE AS AGE

Klicken Sie für die Demo ..

Einfach aber elegant ..

Ferd Shinoda
quelle
5
select floor(datediff (now(), birthday)/365) as age
Hummer1234
quelle
Entschuldigung ... habe es gerade behoben. Er kann je nach Anforderung Boden oder Decke verwenden.
Hummer1234
1
Ja, es wird für diese Genauigkeit nicht funktionieren, wenn OP dies wünscht. Sie müssten jedoch 365 Schaltjahre haben, um einen Altersunterschied von 1 Jahr zu erzielen, nicht wahr?
Hummer1234
2

Einfach:

DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(`birthDate`)), '%Y')+0 AS age
Damonsson
quelle
Nicht einfach im Vergleich zu TIMESTAMPDIFF ()
gwideman
1

Versuche dies:

SET @birthday = CAST('1980-05-01' AS DATE);
SET @today = CURRENT_DATE();

SELECT YEAR(@today) - YEAR(@birthday) - 
  (CASE WHEN
    MONTH(@birthday) > MONTH(@today) OR 
    (MONTH(@birthday) = MONTH(@today) AND DAY(@birthday) > DAY(@today)) 
      THEN 1 
      ELSE 0 
  END);

Es kehrt in diesem Jahr zurück - Geburtsjahr (wie alt die Person in diesem Jahr nach dem Geburtstag sein wird) und passt sich an, je nachdem, ob die Person dieses Jahr noch Geburtstag hatte.

Es leidet nicht unter den Rundungsfehlern anderer hier vorgestellter Methoden.

Frei angepasst von hier

Sklivvz
quelle
1

Da die Frage markiert wird mysql, habe ich die folgende Implementierung, die für mich funktioniert, und ich hoffe, dass ähnliche Alternativen für andere RDBMS verfügbar sind. Hier ist die SQL:

select YEAR(now()) - YEAR(dob) - ( DAYOFYEAR(now()) < DAYOFYEAR(dob) ) as age 
from table 
where ...
Mickeymoon
quelle
1

Einfach machen

SELECT birthdate, (YEAR(CURDATE())-YEAR(birthdate)) AS age FROM `member` 

Geburtsdatum ist ein Feldname, der den Namen des Geburtsdatums beibehält. Nehmen Sie CURDATE (), um mit dem Befehl YEAR () minus mit YEAR () aus dem Feld für das Geburtsdatum auf Jahr umzuschalten

Kuzmiraun
quelle
1
Wenn Sie den Monat und den Tag nicht berücksichtigen, kann die Zahl einen Unterschied von einem Jahr zum tatsächlichen Alter haben
Juan
0

So berechnen Sie das Alter in MySQL:

select
  date_format(now(), '%Y') - date_format(date_of_birth, '%Y') - 
  (date_format(now(), '00-%m-%d') < date_format(date_of_birth, '00-%m-%d'))
as age from table
Mosty Mostacho
quelle
0

Sie können eine Funktion dafür erstellen:

drop function if exists getIdade;

delimiter |

create function getIdade( data_nascimento datetime )
returns int
begin
    declare idade int;
    declare ano_atual int;
    declare mes_atual int;
    declare dia_atual int;
    declare ano int;
    declare mes int;
    declare dia int;

    set ano_atual = year(curdate());
    set mes_atual = month( curdate());
    set dia_atual = day( curdate());

    set ano = year( data_nascimento );
    set mes = month( data_nascimento );
    set dia = day( data_nascimento );

    set idade = ano_atual - ano;

    if( mes > mes_atual ) then
            set idade = idade - 1;
    end if;

    if( mes = mes_atual and dia > dia_atual ) then
            set idade = idade - 1;
    end if;

    return idade;
end|

delimiter ;

Jetzt können Sie das Alter von einem Datum abrufen:

select getIdade('1983-09-16');

Wenn Ihr Datum im Format Ymd H: i: s vorliegt, können Sie Folgendes tun:

select getIdade(substring_index('1983-09-16 23:43:01', ' ', 1));

Sie können diese Funktion überall wiederverwenden;)

Idealmind
quelle
2
Auf jeden Fall der richtige Weg, wenn Sie mit Codezeilen bezahlt werden :-).
Gwideman
0

Ich bevorzuge es, eine Funktion auf diese Weise zu verwenden.

DELIMITER $$ DROP FUNCTION IF EXISTS `db`.`F_AGE` $$
    CREATE FUNCTION `F_AGE`(in_dob datetime) RETURNS int(11)
        NO SQL
    BEGIN
       DECLARE l_age INT;
       IF DATE_FORMAT(NOW(  ),'00-%m-%d') >= DATE_FORMAT(in_dob,'00-%m-%d') THEN
          -- This person has had a birthday this year
          SET l_age=DATE_FORMAT(NOW(  ),'%Y')-DATE_FORMAT(in_dob,'%Y');
        ELSE
          -- Yet to have a birthday this year
          SET l_age=DATE_FORMAT(NOW(  ),'%Y')-DATE_FORMAT(in_dob,'%Y')-1;
       END IF;
       RETURN(l_age);
    END $$

    DELIMITER ;

jetzt zu verwenden

SELECT F_AGE('1979-02-11') AS AGE; 

ODER

SELECT F_AGE(date) AS age FROM table;
HEMM
quelle
0

Dafür gibt es zwei einfache Möglichkeiten:

1-

select("users.birthdate",
            DB::raw("FLOOR(DATEDIFF(CURRENT_DATE, STR_TO_DATE(users.birthdate, '%Y-%m-%d'))/365) AS age_way_one"),

2-

select("users.birthdate",DB::raw("(YEAR(CURDATE())-YEAR(users.birthdate)) AS age_way_two"))
Amine_Dev
quelle