如何使用Oracle获得年,月,日的年龄

问题描述 投票:2回答:4

我正在尝试使用以下格式为每个人打印年龄:

例如:19年,8个月,13天。

我已经google了很多,我注意到有一个特定的函数来计算日期DATEDIFF之间的差异。

但是这个函数在SQL*Plus中不存在,所以我继续尝试使用MONTHS_BETWEEN()和一些运算符。

我的尝试:

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;

我的问题依赖于获得日子。我不知道如何计算天数,使用此功能('尝试除以4或30);我认为我的逻辑很糟糕,但我无法弄明白,任何想法?

sql oracle date-arithmetic
4个回答
6
投票

与Lalit的回答非常相似,但是您可以通过使用add_months来调整整月的总差异来获得准确的天数而不假设每月30天:

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

您可以通过反转计算来验证:

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

3
投票

按年份和月份来衡量年龄很容易,但棘手的部分是DAYS。

如果您可以修复一个月内的天数,则可以获得相同SQL中的天数。例如,使用标准SCOTT.EMP表并假设每个月都有30天:

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.

但是,请注意不是每个月都有30天。因此,您无法获得准确的天数。


UPDATE

我错过了@Alex Poole在他接受的答案中解释的全月差异。我将让这个答案让未来的读者理解错过计算天数的部分。

修改这个:

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

有了这个:

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

0
投票

句法:

SELECT 
  CONCAT(
    TIMESTAMPDIFF(YEAR, ?, NOW()),
    ' Years,',
    TIMESTAMPDIFF(MONTH, ?, NOW()) % 12,
    ' Months,',
    FLOOR(TIMESTAMPDIFF(DAY, ?, NOW()) % 30.4375),
    ' Days'
  ) AS age 
FROM
  DUAL
  • 输入:替换'?'与出生日期。例如,'1994-07-08'
  • 输出:此查询将在'X'年'Y'月和'Z'天返回年龄。

0
投票

获得数月的另一种简化方法是 -

TRUNC(MOD(months_between(sysdate,hiredate),12)) AS months
© www.soinside.com 2019 - 2024. All rights reserved.