2010-06-10 5 views
17

Je veux calculer l'âge actuel à partir de la date de naissance dans ma fonction Oracle.Oracle Calcul de l'âge à partir de Date de naissance et aujourd'hui

Ce que j'utilise est (Today-Dob)/30/12, mais ce n'est pas précis car certains mois ont 31 jours.

Je dois obtenir l'âge correct avec la précision maximale. Comment puis je faire ça?

+0

un coup d'oeil à ce poste, je pense qu'il a ce qu'il vous faut: http://stackoverflow.com/questions/43819/oracle -equivalent-to-sql-server-sybase-datediff – Jay

+1

Juste quelques commentaires pédants. Quand nous disons «âge», il est probablement bon de réfléchir plus attentivement à ce que le mot * signifie *. Normalement, quand quelqu'un dit «âge», ils * signifient en réalité «combien d'anniversaires ont passé». Scientifiquement, si nous exprimons l'âge de deux personnes dans les années, nous ne pouvons pas les comparer parfaitement, indépendamment de la précision, parce que leur * âge réel * sera différent selon leur date de naissance - par ex. étaient-ils nés dans une année bissextile; combien de secondes intercalaires ont été ajoutées/soustraites depuis lors; sont-ils nés avant septembre 1752? (1/2) –

+0

(2/2) Cela dépend de ce que la question est en réalité - à savoir "laquelle de ces deux personnes a vécu le plus longtemps" doit être répondu en utilisant une unité de temps qui ne change pas significativement (par exemple, jours, ou secondes). "Est-ce que cette personne a passé son 18ème anniversaire" est une question différente, qui je dirais est plus proche de ce que la plupart des gens veulent dire par "âge". –

Répondre

33
SQL> select trunc(months_between(sysdate,dob)/12) year, 
    2   trunc(mod(months_between(sysdate,dob),12)) month, 
    3   trunc(sysdate-add_months(dob,trunc(months_between(sysdate,dob)/12)*12+trunc(mod(months_between(sysdate,dob),12)))) day 
    4 from (Select to_date('15122000','DDMMYYYY') dob from dual); 

     YEAR  MONTH  DAY 
---------- ---------- ---------- 
     9   5   26 

SQL> 
2

Et une alternative sans utiliser l'arithmétique et les chiffres (bien qu'il n'y ait rien de mal à cela):

SQL> with some_birthdays as 
    2 (select date '1968-06-09' d from dual union all 
    3 select date '1970-06-10' from dual union all 
    4 select date '1972-06-11' from dual union all 
    5 select date '1974-12-11' from dual union all 
    6 select date '1976-09-17' from dual 
    7 ) 
    8 select trunc(sysdate) today 
    9  , d birth_date 
10  , extract(year from numtoyminterval(months_between(trunc(sysdate),d),'month')) age 
11 from some_birthdays 
12/

TODAY    BIRTH_DATE     AGE 
------------------- ------------------- ---------- 
10-06-2010 00:00:00 09-06-1968 00:00:00   42 
10-06-2010 00:00:00 10-06-1970 00:00:00   40 
10-06-2010 00:00:00 11-06-1972 00:00:00   37 
10-06-2010 00:00:00 11-12-1974 00:00:00   35 
10-06-2010 00:00:00 17-09-1976 00:00:00   33 

5 rows selected. 
13

pour la logique métier, je trouve généralement un nombre décimal (en années) est utile:

select months_between(TRUNC(sysdate), 
         to_date('15-Dec-2000','DD-MON-YYYY') 
        )/12 
as age from dual; 

     AGE 
---------- 
9.48924731 
+0

AskTOM (Connor McDonald) dit qu'il échoue dans très peu de cas: https://asktom.oracle.com/pls/apex/f? p = 100: 11 ::: NO: RP: P11_QUESTION_ID: 9531934000346471628 Recommande celui-ci: trunc ((to_number (to_char (maintenant, 'YYYYMMDD')) - to_number (to_char (naissance, 'YYYYMMDD ')))/10000) –

+0

Salut @ RaúlMoreno, cette formule simple entraîne en réalité une précision beaucoup plus faible. Cet article concerne le calcul d'un âge en années entières uniquement. Connor lui-même dit "C'est une approximation raisonnable, mais encore ... une approximation". Mon algorithme est beaucoup plus précis et ne souffre pas du problème original exprimé dans ce lien (diviser le nombre de jours par 365 sera souvent incorrect, pour des raisons, espérons-le, évidentes). –

+0

Oh! désolé, je n'ai pas remarqué qu'il voulait des décimales. Je voulais l'âge, réel, en années, en tenant compte des années bissextiles, etc.et celui-ci est le seul qui semble avoir toujours raison (et ce n'est pas celui qui divise par 365). –

2

Ou que pensez-vous de cela?

with some_birthdays as 
( 
    select date '1968-06-09' d from dual union all 
    select date '1970-06-10' from dual union all 
    select date '1972-06-11' from dual union all 
    select date '1974-12-11' from dual union all 
    select date '1976-09-17' from dual 
) 
select trunc(sysdate) today 
, d birth_date 
, floor(months_between(trunc(sysdate),d)/12) age 
from some_birthdays; 
2

Cela semble beaucoup plus facile que ce que quelqu'un a suggéré d'autre

select sysdate-to_date('30-jul-1977') from dual; 
+0

Ceci est incorrect car il convertit implicitement une chaîne à une date, ce qui peut très bien aller mal. – Ben

-3

select (SYSDATE-DOB)/365 "âge" de double

2
SELECT 
TRUNC((SYSDATE - TO_DATE(DOB, 'YYYY-MM-DD'))/ 365.25) AS AGE_TODAY FROM DUAL; 

C'est facile et droit le point.

1

âge (années complètes) de la personne:

SELECT 
    TRUNC(months_between(sysdate, per.DATE_OF_BIRTH)/12) AS "Age" 
FROM PD_PERSONS per 
0
SQL>select to_char(to_date('19-11-2017','dd-mm-yyyy'),'yyyy') - to_char(to_date('10-07-1986','dd-mm-yyyy'),'yyyy') year, 
to_char(to_date('19-11-2017','dd-mm-yyyy'),'mm') - to_char(to_date('10-07-1986','dd-mm-yyyy'),'mm') month, 
to_char(to_date('19-11-2017','dd-mm-yyyy'),'dd') - to_char(to_date('10-07-1986','dd-mm-yyyy'),'dd') day from dual; 

     YEAR  MONTH  DAY 
---------- ---------- ---------- 
     31   4   9 
Questions connexes