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

在sql中从出生日期计算年龄,sql,oracle,date-arithmetic,Sql,Oracle,Date Arithmetic,我正在使用oracle执行sql查询。我需要从出生日期开始计算年龄 select sname, TIMESTAMPDIFF(YEAR, DATEOFBIRTH, CURDATE()) from sailors where (select MAX(TIMESTAMPDIFF(YEAR, DATEOFBIRTH, CURDATE())) FROM sailors) TIMESTAMPDIFF(YEAR, DATEOFBIRTH

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

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

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

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;
extractyear from current_date-extractyear from date of Birth从日期到日期之间的年差


按年龄排列的行数按年龄排列的顺序计算行数通常以整年为单位。因此,months_between给出了两个日期之间的整月数;除以12表示年数;应用地板可以去除不需要的部分

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拥有丰富的datetime函数,由于历史原因,这些函数的名称通常与其他类型的RDBMS中的等价函数不同

“显示的不是有效月份。”

这只能在将字符串强制转换为日期时发生。所以假设DATEOFBIRTH列没有日期数据类型。其中的字符串与默认的NLS_日期_格式不匹配。如果默认的日期格式是dd.mm.yyyy,那么像12.23.1993这样的字符串将抛出ORA-01843

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

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

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

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

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

关于sql年龄计算的更多信息,如前所述,整数年龄可以通过以下表达式给出:

floor(months_between(sysdate, dateofbirth)/12)
但是,月与月之间的函数专门处理月末日。这可能会给2月29日出生的人带来一个问题,摘自维基百科:

举个例子,在1998年2月28日,一个出生于1988年2月29日的人是10岁还是9岁?以前的表达式会产生10,但在某些区域是9

在Teradata中,这一表达似乎通常用于允许跳跃者在非跳跃年份的3月1日(而不是2月28日)才满一岁:

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
我运行了以下代码来检查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;

您在系统中定义的timestampdiff和curdate函数是否可能重复?它们不是默认Oracle安装中存在的函数。WHERE子句的格式不正确-似乎需要某种类型的比较运算符来比较sealers和timestamper之间的差异。。。。您可能要寻找的计算两个日期之间月数的函数是。祝你好运。它显示TIMESTAMPDIFF:invalid identifier@almas必须在两个日期之间进行diff,你应该得到diff。这只是为了表明你想知道你做错了。top-n解决方案的经典问题:当两个水手年龄相同时会发生什么?排名在这里会更好。它显示的不是有效月份。我把生日定为1996年3月12日,您应该添加一些解释,而不仅仅是提供代码片段。
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;