2015-10-26 4 views
2

Я пытаюсь напечатать для каждого человека его возраста, используя этот формат:Как получить возраст в годы, месяцы и дни, используя Oracle

например: 19 лет, 8 месяцев, 13 дней.

У меня много googled, и я заметил, что существует определенная функция для расчета разницы между датами 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); Я думаю, что моя логика плоха, но я не могу понять, какие идеи?

+0

Вы должны добавить «оракул» к вам тегам –

+4

я думаю, что это тот же вопрос [здесь] (http://stackoverflow.com/questions/3015431/oracle-age-calculation-from-date-of-birth -и-сегодня) –

ответ

4

Очень похожий на ответ LaLit, но вы можете получить точное количество дней, не предполагая, 30 дней в месяц, используя add_months для корректировки на общую разницу в течение всего месяца:

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 
+0

Это именно то, что я искал. – Lazai

+1

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

2

Получение возраста с точки зрения ЛЕТ и МЕСЯЦЕВ легко, но хитрая часть является то ДНЕЙ.

Если вы можете исправить дни в месяце, вы можете получить количество дней в одном и том же 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

Трудно, я понимаю сейчас. – Lazai

+1

Как это может быть принятым ответом, если он не дает точного количества дней. – Hogan

+1

@Hogan. Я не знал, что OP принял мой ответ, так как я лично хотел бы, чтобы ответ Алекса был принят. Я пропустил расчет дней. Теперь я хотел бы оставить его для будущих читателей, чтобы лучше понять. Если я удалю его, он сломает поток. Это прекрасно, ведь мы все либо учимся, либо разделяем. –

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' Years 'Y' Months и 'Z' days.

 Смежные вопросы

  • Нет связанных вопросов^_^