2010-06-10 88 views
17

Tôi muốn tính tuổi hiện tại từ ngày sinh trong hàm Oracle của tôi.Tính toán tuổi Oracle từ ngày sinh và hôm nay

Điều tôi đang sử dụng là (Today-Dob)/30/12, nhưng điều này không chính xác vì một số tháng có 31 ngày.

Tôi cần có tuổi chính xác với độ chính xác tối đa. Làm thế nào tôi có thể làm điều đó?

+0

hãy xem bài viết này, tôi nghĩ rằng nó có những gì bạn cần: http://stackoverflow.com/questions/43819/oracle -equivalent-to-sql-server-sybase-dateiff – Jay

+1

Chỉ cần một số ý kiến ​​bình luận. Khi chúng ta nói "tuổi", có lẽ là một ý tưởng tốt để suy nghĩ cẩn thận hơn về từ * có nghĩa là gì *. Thông thường, khi ai đó nói "tuổi", họ * thực sự * có nghĩa là "* số ngày kỷ niệm sinh nhật đã trôi qua *". Về mặt khoa học, nếu chúng ta biểu thị tuổi của hai người trong nhiều năm, chúng ta không thể so sánh chúng một cách hoàn hảo, bất kể độ chính xác, vì tuổi * thực tế của chúng sẽ khác nhau tùy thuộc vào thời điểm chúng được sinh ra - ví dụ: họ được sinh ra trong một năm nhuận; bao nhiêu giây nhuận đã được cộng/trừ kể từ đó; họ có được sinh ra trước tháng 9 năm 1752 không? (1/2) –

+0

(2/2) Tùy thuộc vào câu hỏi thực sự là gì - tức là "trong số hai người này sống lâu nhất" nên được trả lời bằng một đơn vị thời gian không thay đổi đáng kể (ví dụ: ngày, hoặc giây). "Người này đã vượt qua sinh nhật thứ 18 của họ" là một câu hỏi khác, mà tôi muốn nói là gần gũi hơn với những gì mọi người có ý nghĩa nhất là "tuổi". –

Trả lời

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

Và một sự thay thế mà không sử dụng bất kỳ số học và số (mặc dù không có gì sai với điều đó là):

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 với logic kinh doanh tôi thường tìm thấy một số thập phân (tính theo năm) là hữu ích:

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) cho biết không thành công trong một số ít trường hợp: https://asktom.oracle.com/pls/apex/f? p = 100: 11 ::: NO: RP: P11_QUESTION_ID: 9531934000346471628 Đề xuất điều này: trunc ((to_number (to_char (now, 'YYYYMMDD')) - to_number (to_char (birth, 'YYYYMMDD ')))/10000) –

+0

Hi @ RaúlMoreno, công thức đơn giản đó thực sự dẫn đến độ chính xác thấp hơn nhiều. Bài viết đó là về việc tính tuổi chỉ trong số nguyên năm. Connor tự nói "Đây là một xấp xỉ hợp lý, nhưng vẫn ... một xấp xỉ". Thuật toán của tôi là chính xác hơn nhiều, và không bị vấn đề ban đầu được thể hiện trong liên kết đó (chia số ngày của 365 thường sẽ không chính xác, vì những lý do hiển nhiên). –

+0

Ồ! xin lỗi, tôi không nhận thấy anh ta muốn những số thập phân. Tôi muốn tuổi tác, thực sự, trong nhiều năm, có tính đến năm nhuận, v.v.và cái này là cái duy nhất có vẻ như luôn luôn đúng (và nó không phải là cái chia cho 365). –

2

Hoặc làm thế nào về điều này?

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

Điều này có vẻ khá dễ dàng hơn so với những gì người khác đã gợi ý

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

Điều này là không chính xác vì nó ngầm chuyển đổi một chuỗi thành một ngày, điều này cũng có thể sai lầm khủng khiếp. – Ben

-3

chọn (SYSDATE-DOB)/365 "Age" từ kép

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

này rất dễ dàng và thẳng đến vấn đề.

1

Tuổi (năm đầy đủ) của Person:

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 
Các vấn đề liên quan