繁体   English   中英

在SQL中从出生日期计算年龄

[英]Calculating age from birth date in sql

我正在使用oracle执行sql查询。 我需要从给定的出生日期开始计算年龄。

select 
    sname,
    TIMESTAMPDIFF(YEAR, DATEOFBIRTH, CURDATE()) 
from 
    sailors 
where 
    (select 
         MAX(TIMESTAMPDIFF(YEAR, DATEOFBIRTH, CURDATE())) 
     FROM sailors) TIMESTAMPDIFF(YEAR, DATEOFBIRTH, CURDATE())

其中, dateofbirth是我的列名, sailors是表名。 但是,它显示错误,缺少关键字。

使用where子句提供条件,并且在那里有一条select语句。 这就是您得到错误的原因。

如果您只需要比较出生日期,请使用

SELECT sname,(DATEOFBIRTH - sysdate) AS "Days"
FROM sailors

这样就足够了

在Oracle中为该行提供最大期限:

select sname, age from (
  select sname, extract(year from current_date) - extract (year from dateofbirth) age,
         row_number() over(order by extract(year from current_date) - extract (year from dateofbirth) desc) rw
  from sailors
) where rw = 1;

extract(year from current_date) - extract (year from dateofbirth)日期开始的年)到日期之间的年数之差

row_number() over(order by age desc) -根据ORDER BY对行进行编号

通常年龄是整年的。 因此, months_between()给出两个日期之间的整月数; 除以12可得出年数; 并应用floor()会删除不需要的分数。

select sname
        , floor(months_between(sysdate, dateofbirth)/12) as age_in_yrs
from sailors
/

如果您想获得最老的水手,则可以将其部署为子查询:

with cte as ( select sname
                  , floor(months_between(sysdate, dateofbirth)/12) as age_in_yrs
              from sailors )
select *
from cte
where age_in_yrs = ( select max(age_in_yrs) from cte )
/

Oracle具有大量的日期时间功能,由于历史原因,它们的名称通常与其他形式的RDBMS中的名称不同。 了解更多


“这表明“无效月份”。”

仅在将字符串转换为日期时才会发生这种情况。 因此,大概您的DATEOFBIRTH列没有DATE数据类型。 并且其中的字符串与默认的NLS_DATE_FORMAT不匹配。 像这样的字符串12.23.1993将抛出ORA-01843 ,如果默认的日期格式为dd.mm.yyyy

因此,您需要编写一个显式的强制转换,因此:

select sname
        , floor(months_between(sysdate, to_date(dateofbirth, 'dd.mm.yyyy'))/12) as age_in_yrs
from sailors
/

请注意,我不得不猜测您的日期是DD.MM还是MM.DD因为从您提供的样本中不明显。 根据需要调整面罩。

select sname, extract(year from sysdate) - extract (year from dateofbirth ) age
from sailors 

--or 

select to_number(to_char(sysdate,'yyyy') - to_number(to_char( dateofbirth ,'yyyy')) 
from sailors  

这是一个T-SQL,可以计算一个人的年龄。 精确到出生那天。

select case 
            when cast(getdate() as date) = cast(dateadd(year, (datediff(year, '1996-09-09', getdate())), '1996-09-09') as date)
                then dateDiff(yyyy,'1996-09-09',dateadd(year, 0, getdate()))
            else dateDiff(yyyy,'1996-09-09',dateadd(year, -1, getdate()))
        end as MemberAge
go

正如APC所指出的,有关sql age计算的更多内容,整数年龄可以由以下表达式给出:

floor(months_between(sysdate, dateofbirth)/12)

但是, months_between函数将特别对待月末。 这可能会给跨跃者(2月29日出生的人)带来一个问题,摘自Wikipedia: 在非le年中跨跃生日的有效法律日期在不同司法管辖区之间有所不同。

举个例子,在1998年2月28日,有人出生于1988年2月29日10岁或9岁吗? 先前的表达式将产生10,但在某些区域为9。

在Teradata中,此表达式似乎通常用于使跳线运动员在3月1日而不是2月28日(不进行跳脱的年份)只满1岁。

select (extract(year from current_date) - extract(year from BIRTH_DATE) (named YEARS))
+ case when current_date - (YEARS (interval year)) < BIRTH_DATE
then -1 else 0 end

我认为此表达式应该具有相同的效果,并且在任何case when都不必调用:

floor(least(months_between(CURRENT_DATE, BIRTH_DATE), months_between(CURRENT_DATE - 1, BIRTH_DATE - 1))/12)

我运行以下代码来检查Teradata中此表达式的有效性:

select O.DATEO, N.DATEN,
(EXTRACT(YEAR FROM N.DATEN) - EXTRACT(YEAR FROM O.DATEO) (NAMED YEARS))
      + CASE WHEN ADD_MONTHS( N.DATEN , - YEARS * 12 )  < O.DATEO
THEN -1 ELSE 0 END  AS AGE1,
floor(least(months_between(N.DATEN, O.DATEO), months_between(N.DATEN -1, O.DATEO- 1))/12) as AGE2,
AGE1 - AGE2
from
(select cast(calendar_date as date) as DATEO from sys_calendar.CALENDAR
where calendar_date between date '2000-01-01'  and date '2013-01-01') as O
inner join 
(select cast(calendar_date as date) as DATEN from sys_calendar.CALENDAR
where calendar_date between date '2000-01-01'  and date '2013-01-01'
) as N
on N.DATEN > O.DATEO
where AGE1 <> AGE2;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM