Oracle 中的日期范围问题。如何正确获取这种格式的日期范围?
Date range problems in Oracle. How do I correctly grab date ranges in this format?
我有这个 Oracle 数据库,它有一个格式如下的日期列表:mm/dd/yy 0:00:00 AM/PM
(1 代表一月,而不是 01;1 代表一天,而不是 01,等等)。
当我尝试查询时:
select DATELIST from CORE.DATE_TEST
where to_date(DATELIST) >= to_date('8/27/2015', 'mm/dd/yy') AND to_date(DATELIST, 'mm/dd/yy') <= to_date('9/27/2015', 'mm/dd/yy');
它给我以下错误:ORA-01843: not a valid month
。我也看不出 27 是一个有效的月份,但如果我尝试
它会接受该输入
当我尝试将其更改为预期的日期格式时:
m/dd/yy
mm/dd/yyyy
m/d/yy
我收到此错误:ORA-01821: date format not recognized
当我将它切换到 dd/mm/yy
时,它有点工作,但不是真的;它给了我无效的结果。
但是,这有效:
select DATELIST from CORE.DATE_TEST
where to_date(DATELIST) >= to_date('8/27/2015', 'mm/dd/yy')
PL/SQL 脚本因以下添加而中断:
AND to_date(DATELIST, 'mm/dd/yy') <= to_date('9/27/2015', 'mm/dd/yy');
当我用这个替换上面的代码时:
SELECT to_date(DATELIST, 'dd/mm/yy')
FROM CORE.DATE_TEST
WHERE DATELIST >= to_date('8/27/2015', 'mm/dd/yy')
AND DATELIST <= to_date('9/27/2015', 'mm/dd/yy');
它可以工作,而且速度快一百万倍,但它无法正确解析日期范围。小于或等于 (<=
) 运算符仅抓取 8/27/2015
和 9/26/2015
之间的数据。不是应该从 8/27/2015 到 9/27/2015 吗?
所以我把最后一行改成这样:
AND DATELIST <= to_date('9/27/2015', 'mm/dd/yy') + 1
...它有效,但我似乎没有正确处理这个问题。
我做错了什么?另外,如果有更好、更有效的方法,我会洗耳恭听。
你的原始问题中有很多问题,我会尝试在这里解决其中的部分或全部问题:
When I try a query such as:
select DATELIST from CORE.DATE_TEST
where to_date(DATELIST) >= to_date('8/27/2015', 'mm/dd/yy') AND to_date(DATELIST, 'mm/dd/yy') <= to_date('9/27/2015', 'mm/dd/yy');
It gives me the following error: ORA-01843: not a valid month
您在指定 to_date(DATELIST)
时未指定日期格式,因此它将默认为默认日期格式的 NLS 设置。每当您使用 TO_DATE 以防止这种情况发生并确保您的日期格式明确时,您应该始终指定日期格式(并且您正在使用 yy
但您指定了 4 位数的年份,因此您应该使用yyyy
).
试试这个(假设 DATELIST
是 DATE
数据类型):
select TO_CHAR(DATELIST, 'DD-MON-YYYY HH24:MI:SS') -- Use whatever date format is clearest to you
from CORE.DATE_TEST
where DATELIST >= to_date('8/27/2015 00:00:00', 'mm/dd/yyyy hh24:mi:ss') AND DATELIST <= to_date('9/27/2015 23:59:59', 'mm/dd/yyyy hh24:mi:ss');
如果 DATELIST
是 VARCHAR2
,那么您需要查看值在列中存储的日期格式,并相应地格式化查询。
The lesser-than-or-equal-to (<=) operator is only grabbing data
between 8/27/2015, and 9/26/2015. Isn't it supposed to get 8/27/2015
to 9/27/2015?
当您使用 TO_DATE
且未指定日期的时间部分时,它默认为 00:00:00 表示小时、分钟和秒。如果您想要完整的日期范围,请尝试更明确:
SELECT to_date(DATELIST, 'dd/mm/yy hh24:mi:ss')
FROM CORE.DATE_TEST
WHERE DATELIST >= to_date('8/27/2015 00:00:00', 'mm/dd/yyyy hh24:mi:ss')
AND DATELIST <= to_date('9/27/2015 23:59:59', 'mm/dd/yyyy hh24:mi:ss');
查询速度快得多的原因是,我怀疑您在 DATELIST
列上有一个索引,当您用 TO_DATE
调用(例如 TO_DATE(DATELIST, 'mm/dd/yyyy')
.
如果 DATELIST
的数据类型是 DATE
则保留它,如果它是 VARCHAR2
那么您还有一些额外的日期格式问题。
希望对您有所帮助
编辑:
我认为您的问题与 DATE
数据类型 DATELIST 的隐藏时间部分有关。
如果你有以下价值:
2015 年 9 月 27 日 10:35:12
即使您不关心该日期的 10:35:12 部分,它仍然存在。如果您随后尝试使用以下 where 子句:
WHERE DATELIST >= TO_DATE('09/26/2015', 'MM/DD/RRRR')
AND DATELIST <= TO_DATE('09/27/2015', 'MM/DD/RRRR');
那么该值将不会被拾取,因为它大于:
2015 年 9 月 27 日 00:00:00。
您需要将上限提高一天或指定时间部分,例如:
WHERE DATELIST >= TO_DATE('09/26/2015 00:00:00', 'MM/DD/RRRR HH24:MI:SS')
AND DATELIST <= TO_DATE('09/27/2015 23:59:59', 'MM/DD/RRRR HH24:MI:SS');
编辑2:
与 OP 合作,他说这有效:
SELECT to_date(DATELIST, 'dd/mm/yy') as Date_Accessed
FROM CORE.DATE_TEST
WHERE (trunc(DATELIST) >= to_date('9/27/2015', 'mm/dd/yy'))
AND (trunc(DATELIST) <= to_date('9/30/2015', 'mm/dd/yy'));
虽然这会破坏 DATELIST 列上的任何索引。
不使用 to_date,而是使用 ANSI 日期文字:
DATE '2015-09-27'
来自 oracle 文档:
The ANSI date literal contains no time portion, and must be specified
in exactly this format ('YYYY-MM-DD').
我有这个 Oracle 数据库,它有一个格式如下的日期列表:mm/dd/yy 0:00:00 AM/PM
(1 代表一月,而不是 01;1 代表一天,而不是 01,等等)。
当我尝试查询时:
select DATELIST from CORE.DATE_TEST
where to_date(DATELIST) >= to_date('8/27/2015', 'mm/dd/yy') AND to_date(DATELIST, 'mm/dd/yy') <= to_date('9/27/2015', 'mm/dd/yy');
它给我以下错误:ORA-01843: not a valid month
。我也看不出 27 是一个有效的月份,但如果我尝试
当我尝试将其更改为预期的日期格式时:
m/dd/yy
mm/dd/yyyy
m/d/yy
我收到此错误:ORA-01821: date format not recognized
当我将它切换到 dd/mm/yy
时,它有点工作,但不是真的;它给了我无效的结果。
但是,这有效:
select DATELIST from CORE.DATE_TEST
where to_date(DATELIST) >= to_date('8/27/2015', 'mm/dd/yy')
PL/SQL 脚本因以下添加而中断:
AND to_date(DATELIST, 'mm/dd/yy') <= to_date('9/27/2015', 'mm/dd/yy');
当我用这个替换上面的代码时:
SELECT to_date(DATELIST, 'dd/mm/yy')
FROM CORE.DATE_TEST
WHERE DATELIST >= to_date('8/27/2015', 'mm/dd/yy')
AND DATELIST <= to_date('9/27/2015', 'mm/dd/yy');
它可以工作,而且速度快一百万倍,但它无法正确解析日期范围。小于或等于 (<=
) 运算符仅抓取 8/27/2015
和 9/26/2015
之间的数据。不是应该从 8/27/2015 到 9/27/2015 吗?
所以我把最后一行改成这样:
AND DATELIST <= to_date('9/27/2015', 'mm/dd/yy') + 1
...它有效,但我似乎没有正确处理这个问题。
我做错了什么?另外,如果有更好、更有效的方法,我会洗耳恭听。
你的原始问题中有很多问题,我会尝试在这里解决其中的部分或全部问题:
When I try a query such as:
select DATELIST from CORE.DATE_TEST
where to_date(DATELIST) >= to_date('8/27/2015', 'mm/dd/yy') AND to_date(DATELIST, 'mm/dd/yy') <= to_date('9/27/2015', 'mm/dd/yy');
It gives me the following error: ORA-01843: not a valid month
您在指定 to_date(DATELIST)
时未指定日期格式,因此它将默认为默认日期格式的 NLS 设置。每当您使用 TO_DATE 以防止这种情况发生并确保您的日期格式明确时,您应该始终指定日期格式(并且您正在使用 yy
但您指定了 4 位数的年份,因此您应该使用yyyy
).
试试这个(假设 DATELIST
是 DATE
数据类型):
select TO_CHAR(DATELIST, 'DD-MON-YYYY HH24:MI:SS') -- Use whatever date format is clearest to you
from CORE.DATE_TEST
where DATELIST >= to_date('8/27/2015 00:00:00', 'mm/dd/yyyy hh24:mi:ss') AND DATELIST <= to_date('9/27/2015 23:59:59', 'mm/dd/yyyy hh24:mi:ss');
如果 DATELIST
是 VARCHAR2
,那么您需要查看值在列中存储的日期格式,并相应地格式化查询。
The lesser-than-or-equal-to (<=) operator is only grabbing data between 8/27/2015, and 9/26/2015. Isn't it supposed to get 8/27/2015 to 9/27/2015?
当您使用 TO_DATE
且未指定日期的时间部分时,它默认为 00:00:00 表示小时、分钟和秒。如果您想要完整的日期范围,请尝试更明确:
SELECT to_date(DATELIST, 'dd/mm/yy hh24:mi:ss')
FROM CORE.DATE_TEST
WHERE DATELIST >= to_date('8/27/2015 00:00:00', 'mm/dd/yyyy hh24:mi:ss')
AND DATELIST <= to_date('9/27/2015 23:59:59', 'mm/dd/yyyy hh24:mi:ss');
查询速度快得多的原因是,我怀疑您在 DATELIST
列上有一个索引,当您用 TO_DATE
调用(例如 TO_DATE(DATELIST, 'mm/dd/yyyy')
.
如果 DATELIST
的数据类型是 DATE
则保留它,如果它是 VARCHAR2
那么您还有一些额外的日期格式问题。
希望对您有所帮助
编辑:
我认为您的问题与 DATE
数据类型 DATELIST 的隐藏时间部分有关。
如果你有以下价值: 2015 年 9 月 27 日 10:35:12
即使您不关心该日期的 10:35:12 部分,它仍然存在。如果您随后尝试使用以下 where 子句:
WHERE DATELIST >= TO_DATE('09/26/2015', 'MM/DD/RRRR')
AND DATELIST <= TO_DATE('09/27/2015', 'MM/DD/RRRR');
那么该值将不会被拾取,因为它大于: 2015 年 9 月 27 日 00:00:00。
您需要将上限提高一天或指定时间部分,例如:
WHERE DATELIST >= TO_DATE('09/26/2015 00:00:00', 'MM/DD/RRRR HH24:MI:SS')
AND DATELIST <= TO_DATE('09/27/2015 23:59:59', 'MM/DD/RRRR HH24:MI:SS');
编辑2: 与 OP 合作,他说这有效:
SELECT to_date(DATELIST, 'dd/mm/yy') as Date_Accessed
FROM CORE.DATE_TEST
WHERE (trunc(DATELIST) >= to_date('9/27/2015', 'mm/dd/yy'))
AND (trunc(DATELIST) <= to_date('9/30/2015', 'mm/dd/yy'));
虽然这会破坏 DATELIST 列上的任何索引。
不使用 to_date,而是使用 ANSI 日期文字:
DATE '2015-09-27'
来自 oracle 文档:
The ANSI date literal contains no time portion, and must be specified in exactly this format ('YYYY-MM-DD').