2010-06-10 30 views
17

Oracle işlevimde Doğum Tarihi Geçerli Yaşı hesaplamak istiyorum.Oracle Doğum Tarihi ve Bugün Yaşı Yaşı hesaplama

Kullandığım şey (Today-Dob)/30/12, ancak bazı ayların 31 günü olduğu için bu doğru değil.

Doğru yaşını maksimum hassasiyetle elde etmem gerekiyor. Bunu nasıl yapabilirim?

+0

bu yazı bir göz atın, ben neye ihtiyacınız olduğunu düşünüyor: http://stackoverflow.com/questions/43819/oracle Eşdeğerli-sql-sunucu-sybase-datediff – Jay

+1

Sadece bazı pedantic yorumlar. "Yaş" dediğimiz zaman, kelimenin ne anlama geldiği hakkında daha dikkatli düşünmek muhtemelen iyi bir fikirdir *. Normalde, bir kişi “yaş” derken, aslında * * “doğum günü yıldönümlerinin kaç gün * geçtiğini” belirtir. Bilimsel olarak, eğer iki insanın yaşlarını yıllardır ifade edersek, onları kesin olarak karşılaştırırız, doğruluktan bağımsız olarak, çünkü * gerçek yaş * doğdukları zamana bağlı olarak farklı olacaktır - örn. bir yıl içinde doğmuşlardı; o zamandan bu yana kaç saniye kaç saniye eklenmiş/çıkarılmıştır; 1752'den önce mi doğmuşlar? (1/2) –

+0

(2/2) Sorunun gerçekte ne olduğuna bağlı olarak - yani "bu iki insandan hangisinin en uzun yaşadığı" ifadesi, önemli ölçüde değişmeyen bir zaman birimi kullanılarak yanıtlanmalıdır (örneğin günler veya saniye). "Bu kişi 18. yaş gününü geçti mi?" Sorusu, çoğu kişinin "yaş" ile ne demek istediğine daha yakın olduğunu söyleyen farklı bir sorudur. –

cevap

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

Ve (bunda yanlış bir şey yok rağmen) herhangi aritmetik ve rakamları kullanmadan alternatif:

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

iş mantığı için genellikle (yıl olarak) bir ondalık sayı bulmak yararlıdır:

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) çok az durumda başarısız diyor ki: https://asktom.oracle.com/pls/apex/f? p = 100: 11 ::: NO: RP: P11_QUESTION_ID: 9531934000346471628 Bunu önerir: trunc ((to_number (to_char (şimdi, 'YYYYMMDD')) - to_number (to_char (doğum, 'YYYYMMDD) ')))/10000) –

+0

Hi @ RaúlMoreno, bu basit formül aslında daha düşük hassasiyetle sonuçlanır. Bu makale sadece bir tamyılyılında bir yaşın hesaplanmasıyla ilgilidir. Connor kendisi "Bu makul bir yaklaşımdır, ama yine de ... bir yaklaşım" diyor. Algoritmam çok daha doğru ve bu bağlantıda ifade edilen asıl sorundan muzdarip değil (365 gün sayısının bölünmesi genellikle umarsız nedenlerle yanlıştır). –

+0

Oh! Üzgünüm, ondalık istediğini fark etmedim. Yıllar yaşarken, yılların gerçek yaşını, vb. Hesaba katmak istiyorum.ve bu, her zaman doğru olana benzeyen tek şeydir (ve 365'e bölen de değil). –

2

Ya buna ne dersin?

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

Bu başkasının önerdiği olandan oldukça kolay görünüyor

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

Yanlış bir şekilde bir dizeyi bir tarihe dönüştürdüğünden yanlış olan bu yanlıştır. – Ben

-3

seçme (SYSDATE-DOB) ikili

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

den/365 "Yaş" Bu kolay ve düz etmektir nokta.

1

Yaş Kişinin (tam yıl):

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 
İlgili konular