我的Oracle表有以下2个变量的1,000个观察值:(两个字段都是varchar)
ID datecreate
ABC 24/12/2016 05:32:07
我想过滤日期。我试过以下但无济于事......
select *
from table
where datecreate >= to_date('01/02/2018 00:00:00', 'dd/mm/yyyy hh24:mi:ss') and
datecreate <= to_date('28/02/2018 23:59:00', 'dd/mm/yyyy hh24:mi:ss')
我一直收到以下错误......
ORA-01843: not a valid month
01843. 00000 - "not a valid month"
*Cause:
*Action:
我错过了一些明显的东西吗?
由于
答案 0 :(得分:2)
默认NLS_DATE_FORMAT目前是DD-MON-RR。因此,定义为字符串的datecreate列将隐式转换为该格式。值12与DEC不同,因此出错。要么使用正确的格式,要么将其转换为类似于下面的日期。
select *
from tbl
where to_date(datecreate, 'dd/mm/yyyy hh24:mi:ss') >=
to_date('01/02/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss')
and to_date(datecreate, 'dd/mm/yyyy hh24:mi:ss') <=
to_date('28/02/2018 23:59:00', 'dd/mm/yyyy hh24:mi:ss')
答案 1 :(得分:2)
多次强调,在数据库中,DATE
和TIME
不应存储为字符串。然而,每天都会提出几个问题,这完全是由于这种不良做法造成的。
请注意,在Oracle中,日期时间可以存储为DATE
类型或TIMESTAMP
(带或不带TIMEZONE
)。 DATE
类型也包含时间组件。
TO_DATE
函数可以解决问题。在使用日期时,最好使用DATE
格式的标准'YYYY-MM-DD'
文字,这是大多数DBMS所理解的。 (例如: - DATE '2018-02-28'
)。
此外,当您可以使用'28/02/2018 23:59:00'
文字时,不需要对此类边界情况使用TRUNC
或DATE
函数。因此,您的查询可以重写为
SELECT *
FROM yourtable
WHERE TO_DATE(datecreate, 'dd/mm/yyyy hh24:mi:ss') >= DATE '2018-02-01'
AND TO_DATE(datecreate, 'dd/mm/yyyy hh24:mi:ss') < DATE '2018-02-28' + 1
或< DATE '2020-02-29'
如果您知道这是闰年。
如果您真的要考虑到23:59
分钟,那么TIMESTAMP
文字可以与TO_TIMESTAMP
函数一起使用。
.. AND TO_TIMESTAMP(datecreate, 'dd/mm/yyyy hh24:mi:ss') <
TIMESTAMP '2018-02-28 23:59:00'