2015-10-26 4 views
2

Je suis en train d'imprimer pour chaque personne son âge en utilisant ce format:Comment obtenir l'âge en années, mois et jours en utilisant Oracle

par exemple: 19 ans, 8 mois, 13 jours.

J'ai beaucoup googlé et j'ai remarqué qu'il y a une fonction spécifique pour calculer la différence entre les dates DATEDIFF.

Cependant cette fonction n'existe pas dans SQL*Plus, donc j'ai continué à essayer en utilisant MONTHS_BETWEEN() et quelques opérateurs.

Ma tentative:

SELECT name , ' ' || 
    FLOOR(MONTHS_BETWEEN(to_date(SYSDATE),to_date(date_of_birth))/12)||' years ' || 
    FLOOR(MOD(MONTHS_BETWEEN(to_date(SYSDATE),to_date(date_of_birth)),12)) || ' months ' || 
    FLOOR(MOD(MOD(MONTHS_BETWEEN(to_date(SYSDATE),to_date(date_of_birth)),12),4))|| ' days ' AS "Age" 
FROM persons; 

Ma question repose sur l'obtention des jours. Je ne sais pas comment calculer les jours, en utilisant cette fonction ('essayé de diviser par 4, ou 30); Je pense que ma logique est mauvaise mais je n'arrive pas à comprendre, des idées?

+0

Vous devez ajouter "oracle" pour vous des tags –

+4

Je pense qu'il est la même question [ici] (http://stackoverflow.com/questions/3015431/oracle-age-calculation-from-date-of-birth -et-aujourd'hui) –

Répondre

4

Très similaire à la réponse de Lalit, mais vous pouvez obtenir un nombre précis de jours sans prendre 30 jours par mois, en utilisant add_months pour ajuster la différence totale d'un mois:

select sysdate, 
    hiredate, 
    trunc(months_between(sysdate,hiredate)/12) as years, 
    trunc(months_between(sysdate,hiredate) - 
    (trunc(months_between(sysdate,hiredate)/12) * 12)) as months, 
    trunc(sysdate) 
    - add_months(hiredate, trunc(months_between(sysdate,hiredate))) as days 
from emp; 

SYSDATE HIREDATE  YEARS  MONTHS  DAYS 
---------- ---------- ---------- ---------- ---------- 
2015-10-26 1980-12-17   34   10   9 
2015-10-26 1981-02-20   34   8   6 
2015-10-26 1981-02-22   34   8   4 
2015-10-26 1981-04-02   34   6   24 
2015-10-26 1981-09-28   34   0   28 
2015-10-26 1981-05-01   34   5   25 
2015-10-26 1981-06-09   34   4   17 
2015-10-26 1982-12-09   32   10   17 
2015-10-26 1981-11-17   33   11   9 
2015-10-26 1981-09-08   34   1   18 
2015-10-26 1983-01-12   32   9   14 
2015-10-26 1981-12-03   33   10   23 
2015-10-26 1981-12-03   33   10   23 
2015-10-26 1982-01-23   33   9   3 

Vous pouvez vérifier en inversant le calcul:

with tmp as (
    select trunc(sysdate) as today, 
     hiredate, 
     trunc(months_between(sysdate,hiredate)/12) as years, 
     trunc(months_between(sysdate,hiredate) - 
     (trunc(months_between(sysdate,hiredate)/12) * 12)) as months, 
     trunc(sysdate) 
     - add_months(hiredate, trunc(months_between(sysdate,hiredate))) as days 
    from emp 
) 
select * from tmp 
where today != add_months(hiredate, (12 * years) + months) + days; 

no rows selected 
+0

C'est exactement ce que je cherchais. – Lazai

+1

'add_months (hiredate, trunc (months_between (sysdate, hiredate)))' Nice !!! –

2

Obtenir l'âge en termes de ANS et MOIS est facile, mais la partie la plus délicate est la les jours.

Si vous pouvez corriger les jours dans un mois, vous pouvez obtenir le nombre de jours dans le même SQL. Par exemple, en utilisant la table standard SCOTT.EMP et en supposant chaque mois a 30 jours:

SQL> SELECT SYSDATE, 
    2  hiredate, 
    3  TRUNC(months_between(SYSDATE,hiredate)/12) years, 
    4  TRUNC(months_between(SYSDATE,hiredate) - 
    5  (TRUNC(months_between(SYSDATE,hiredate)/12)*12)) months, 
    6  TRUNC((months_between(SYSDATE,hiredate) - 
    7  TRUNC(months_between(SYSDATE,hiredate)))*30) days 
    8 FROM emp; 

SYSDATE HIREDATE  YEARS  MONTHS  DAYS 
---------- ---------- ---------- ---------- ---------- 
2015-10-26 1980-12-17   34   10   9 
2015-10-26 1981-02-20   34   8   6 
2015-10-26 1981-02-22   34   8   4 
2015-10-26 1981-04-02   34   6   23 
2015-10-26 1981-09-28   34   0   28 
2015-10-26 1981-05-01   34   5   24 
2015-10-26 1981-06-09   34   4   17 
2015-10-26 1982-12-09   32   10   17 
2015-10-26 1981-11-17   33   11   9 
2015-10-26 1981-09-08   34   1   18 
2015-10-26 1983-01-12   32   9   14 
2015-10-26 1981-12-03   33   10   22 
2015-10-26 1981-12-03   33   10   22 
2015-10-26 1982-01-23   33   9   3 

14 rows selected. 

Mais, sachez pas tous les mois a 30 jours. Donc, vous ne pouvez pas avoir la précision avec le nombre de jours.


MISE À JOUR

I Missed la différence totale tout mois qui Poole a expliqué @ Alex dans sa réponse acceptée. Je laisserai cette réponse aux futurs lecteurs pour comprendre la partie qui a manqué au sujet du calcul du nombre de jours.

Modifier ceci:

TRUNC((months_between(SYSDATE,hiredate) -  
TRUNC(months_between(SYSDATE,hiredate)))*30) days 

Avec ceci:

TRUNC(SYSDATE) - add_months(hiredate, TRUNC(months_between(sysdate,hiredate))) 
+0

Tricky en effet, je comprends maintenant. – Lazai

+1

Comment cela peut-il être une réponse acceptée quand il ne donne pas un nombre précis de jours – Hogan

+1

@Hogan Je n'étais pas au courant OP a accepté ma réponse, comme je voudrais personnellement que la réponse d'Alex soit acceptée. J'ai raté le calcul des jours. Maintenant, j'aimerais que les futurs lecteurs comprennent mieux. Si je le supprime, cela casserait le flux. C'est bien, après tout, nous sommes tous en train d'apprendre ou de partager. –

0

Syntaxe:

SELECT 
    CONCAT(
    TIMESTAMPDIFF(YEAR, ?, NOW()), 
    ' Years,', 
    TIMESTAMPDIFF(MONTH, ?, NOW()) % 12, 
    ' Months,', 
    FLOOR(TIMESTAMPDIFF(DAY, ?, NOW()) % 30.4375), 
    ' Days' 
) AS age 
FROM 
    DUAL 
  • Entrée: remplacer?avec date de naissance. Par exemple, '1994-07-08'
  • Sortie: Cette requête renverra l'âge en 'X' Ans 'Y' Mois et 'Z' jours.