关于日期的SQL查询

时间:2017-05-03 14:49:16

标签: sql oracle sysdate

  <intercept-url pattern="/home" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>
  <intercept-url pattern="/home/**" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>
SYSDATE
-------
03-May-17
select sysdate
from dual;
SYSDATE
-------
02-May-17
==============

如果运行以下sql查询

select sysdate -1 
from dual;

我得到了答案 30-NOV-15

===== 任何人都能帮我理解这种行为吗?

1 个答案:

答案 0 :(得分:0)

文档已a section on datetime/interval arithmetic。添加到日期或从日期中减去的数字被视为一天的一小部分:

  

例如,明天是SYSDATE + 1。 SYSDATE - 7是一周前。 SYSDATE +(10/1440)距现在十分钟

正如@mathguy所指出的,Oracle中的所有日期都有一个时间组件,sysdate具有当前服务器时间。如果显示日期/时间的完整值,您可以看到发生了什么。您可以使用to_char()和合适的格式明确地执行此操作,但为了简洁起见,我将更改会话NLS设置:

alter session set nls_date_format = 'SYYYY-MM-DD HH24:MI:SS';

select sysdate, sysdate - 1
from dual;

SYSDATE              SYSDATE-1           
-------------------- --------------------
 2017-05-03 16:17:47  2017-05-02 16:17:47

两者都显示相同的时间,但在不同的日子。

你可以truncate a date降低它的精确度;默认情况下trunc(sysdate)将时间元素归零,使其变为今天午夜而不是当前时间。

您的第三个示例稍微有点了,因为您使用的是不匹配的值和格式掩码;凭借2位数年份和4位数YYYY面具,年份不会像您预期的那样结束:

select to_date('01-DEC-15','DD-MON-YYYY'), to_date('01-DEC-15','DD-MON-YYYY') - 1
from dual;

TO_DATE('01-DEC-15', TO_DATE('01-DEC-15',
-------------------- --------------------
 0015-12-01 00:00:00  0015-11-30 00:00:00

那可能不是你想要的。 RRRR掩码更宽容,如手册中所述:

select to_date('01-DEC-15','DD-MON-RRRR'), to_date('01-DEC-15','DD-MON-RRRR') - 1
from dual;

TO_DATE('01-DEC-15', TO_DATE('01-DEC-15',
-------------------- --------------------
 2015-12-01 00:00:00  2015-11-30 00:00:00

但最好还是提供一个完整的4位数年份:

select to_date('01-DEC-2015','DD-MON-YYYY'), to_date('01-DEC-2015','DD-MON-YYYY') - 1
from dual;

TO_DATE('01-DEC-2015 TO_DATE('01-DEC-2015
-------------------- --------------------
 2015-12-01 00:00:00  2015-11-30 00:00:00

或更简单地说,使用date literal

select date '2015-12-01', date '2015-12-01' - 1
from dual;

DATE'2015-12-01'     DATE'2015-12-01'-1  
-------------------- --------------------
 2015-12-01 00:00:00  2015-11-30 00:00:00

这也避免了日期语言的问题; 'APR'在语言(特别是NLS_DATE_LANGAUGE - 不是英语的会话中得不到认可(除非它巧合地是另一种语言的公认缩写,但有几个月会仍然失败)。使用月份数字会更好。如果必须使用名称或缩写,则可以使用to_date()的可选第三个参数指定它们所使用的语言。但是如果你没有从字符串变量转换,文字仍然更容易。