【问题标题】:Oracle - Selecting employees which were hired in the last 20 yearsOracle - 选择过去 20 年雇用的员工
【发布时间】:2014-07-29 06:37:56
【问题描述】:

我不能使用months_between,只允许玩DATE,所以我得到了这个:

select * from emp
where ((SYSDATE- hiredate)/(365+1/4-1/100+1/400)) >= ((SYSDATE/(365+1/4-1/100+1/400))-20);

我不明白为什么我会出错

(SYSDATE/(365+1/4-1/100+1/400))-20

说它是无效的数据类型“不一致的数据类型:预期的 %s 得到 %s”时

(SYSDATE-hiredate)/(365+1/4-1/100+1/400)

工作正常,没有错误,WTF?

PS:使用 (365+1/4-1/100+1/400) 的例子是出生日期,更精确:

((SYSDATE- birth_date)/(365+1/4-1/100+1/400)) >=18

【问题讨论】:

  • 也许使用hiredate >= add_months(sysdate, -12 * 20) 或者间隔会更清晰。
  • 我会尝试 select to_number (sysdate-to_date('19940610','yyyymmdd'))/7305 from dual;然后比较它(注意:20 年总是有固定的天数)

标签: sql oracle


【解决方案1】:

sysdate 返回当前日期和时间。

在下面的第二个测试用例中,您减去两个返回的日期 表示两个日期之间的天数的数值,因此可以进行计算(可以进行除法)。

(SYSDATE-hiredate)/(365+1/4-1/100+1/400)

在下面的第一个测试用例中,您直接尝试划分日期类型值。 您不能在 oracle 中划分日期数据类型。相反,您可以添加任何值,例如 x (sysdate +x),这意味着您将 x 天添加到日期值。

(SYSDATE/(365+1/4-1/100+1/400))-5

如果您想将sysdate 转换为数字,您可以尝试如下所示

select to_number(to_char(sysdate, 'yyyymmddhh24miss')) from dual; 

今天会返回 DATE+TIME,例如 20140608165750

(或)

select to_number(to_char(sysdate, 'yyyymmdd')) from dual;

结果将是 20140608(仅 DATE 部分)

【讨论】:

    【解决方案2】:

    根据 Oracle 减去两个 Date 数据类型,您将得到一个 Number 数据类型。 来自 Oracle 文档:Reference

    所以这部分查询
    ((SYSDATE- birth_date)/(365+1/4-1/100+1/400)) >=18 返回一个数字,而

    在此声明中
    (SYSDATE/(365+1/4-1/100+1/400))-5 sysdate 仍被视为日期数据类型,这就是您收到错误的原因。您可以显式使用to_number 将 sysdate 转换为数字。

    编辑:试试这个((to_number(to_char(SYSDATE,'DDMMYYYY'))/(365+1/4-1/100+1/400))-5) 将您的 sysdate 日期数据类型转换为数字数据类型。因此,您的选择查询应如下所示

    select * from emp
    where ((SYSDATE- hiredate)/(365+1/4-1/100+1/400)) >= ((to_number(to_char(SYSDATE,'DDMMYYYY'))/(365+1/4-1/100+1/400))-5);
    

    【讨论】:

    • select to_number(sysdate) from dual;获取无效号码错误:S
    猜你喜欢
    • 2012-01-05
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    相关资源
    最近更新 更多