我有一个包含以下字段的表:
Reports (表名) Rep_Date (日期) Rep_Time (日期)
Rep_Time字段的值类似于'01/01/1753 07:30:00‘,即时间部分是相关的。我写了以下查询:
select Reports.pid, MaxDate from Reports
INNER JOIN (
select pid, max(TO_DATE(TO_CHAR(REP_DATE, 'DD/MM/YYYY')
|| TO_CHAR(REP_TIME, 'HH24:MI:SS'), 'DD/MM/YYYY HH24:MI:SS')) As MaxDate
from reports
group by pid
) ReportMaxDate
on Reports.PID = ReportMaxDate.PID
AND To_Date(To_Char(MaxDate, 'DD/MM/YYYY')) = REP_DATE
WHERE REPORTS.PID=61
查询的派生表部分运行,但是当我运行整个查询时,我得到一个错误:“不是一个有效的月份”。为什么会这样呢?
为了帮助调试这一点,如果我运行以下查询:
select rep_date, rep_time from reports where pid=61 and rownum=1
我得到了:
Rep_Date = 01/04/2009
Rep_Time = 01/01/1753 13:00:00
更新15:58我现在可以执行以下查询:
select Reports.pid, MaxDate from Reports
INNER JOIN (
select pid, max(TO_DATE(TO_CHAR(REP_DATE, 'DD/MM/YYYY')
|| TO_CHAR(REP_TIME, 'HH24:MI:SS'), 'DD/MM/YYYY HH24:MI:SS')) As MaxDate
from reports group by pid
) ReportMaxDate
on Reports.PID = ReportMaxDate.PID
AND to_date(to_char(maxdate,'MM/DD/YYYY'),'MM/DD/YYYY') = REP_DATE
WHERE REPORTS.PID=61
但是,我需要在WHERE
子句中再添加一条语句,将MaxDate的时间部分与rep_time进行比较:to_date(to_char(maxdate,'MM/DD/YYYY'),'MM/DD/YYYY') = REP_DATE
不工作。
发布于 2012-09-26 14:32:04
1.
To_Date(To_Char(MaxDate, 'DD/MM/YYYY')) = REP_DATE
是导致问题的原因。当您使用不带时间格式的to_date时,oracle将使用当前会话的NLS格式进行转换,在您的情况下可能不是"DD/MM/YYYY“。看看这个。
SQL> select sysdate from dual;
SYSDATE
---------
26-SEP-12
Which means my session's setting is DD-Mon-YY
SQL> select to_char(sysdate,'MM/DD/YYYY') from dual;
TO_CHAR(SY
----------
09/26/2012
SQL> select to_date(to_char(sysdate,'MM/DD/YYYY')) from dual;
select to_date(to_char(sysdate,'MM/DD/YYYY')) from dual
*
ERROR at line 1:
ORA-01843: not a valid month
SQL> select to_date(to_char(sysdate,'MM/DD/YYYY'),'MM/DD/YYYY') from dual;
TO_DATE(T
---------
26-SEP-12
2.
更重要的是,为什么要先转换为char,然后再转换为date,而不是直接比较
MaxDate = REP_DATE
如果要在比较之前忽略MaxDate中的时间部分,则应使用..
trunc(MaxDate ) = rep_date
而不是。
==Update :基于更新的问题。
Rep_Date = 01/04/2009 Rep_Time = 01/01/1753 13:00:00
我认为问题要复杂得多。如果rep_time仅为时间,则不能将其作为日期存储在数据库中。它必须是字符串或日期到时间的间隔,或者以秒为数值(感谢Alex,请参阅this)。如果可能,我建议使用一个同时包含日期和时间的列rep_date,并直接将其与最大日期列进行比较。
如果它是一个正在运行的系统,并且您无法控制repdate,您可以尝试这样做。
trunc(rep_date) = trunc(maxdate) and
to_char(rep_date,'HH24:MI:SS') = to_char(maxdate,'HH24:MI:SS')
无论哪种方式,时间存储都不正确(您可以从1753年看出),而且未来可能还会有其他问题。
发布于 2013-01-06 21:52:50
要了解实际的日期格式,请使用sysdate插入一条记录。这样您就可以找到实际的日期格式。例如
insert into emp values(7936, 'Mac', 'clerk', 7782, sysdate, 1300, 300, 10);
现在,选择插入的记录。
select ename, hiredate from emp where ename='Mac';
结果是
ENAME HIREDATE
Mac 06-JAN-13
好了,现在找到了您实际的日期格式。
发布于 2020-11-23 05:09:43
您还可以使用ALTER session命令为会话更改此数据库参数的值,并根据需要使用它
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MM-YYYY';
SELECT TO_DATE('05-12-2015') FROM dual;
05/12/2015
https://stackoverflow.com/questions/12603975
复制相似问题