我有一个包含以下字段的表:
报告(表名)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不起作用。
WHERE
to_date(to_char(maxdate,'MM/DD/YYYY'),'MM/DD/YYYY') = REP_DATE
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然后再转换为日期,而不是直接进行比较
MaxDate = REP_DATE
如果要在比较之前忽略MaxDate中的时间分量,则应使用。
trunc(MaxDate ) = rep_date
反而。
==更新:基于更新的问题。
我认为问题更加复杂。如果rep_time仅是时间,则不能将其作为日期存储在数据库中。它必须是一个字符串或日期到时间间隔,或以数字表示,以秒为单位(感谢Alex,请参见this)。如果可能的话,我建议使用一列同时包含日期和时间的rep_date并将其直接与max date列进行比较。
如果它是正在运行的系统,并且您无法控制repdate,则可以尝试此操作。
trunc(rep_date) = trunc(maxdate) and to_char(rep_date,'HH24:MI:SS') = to_char(maxdate,'HH24:MI:SS')
无论哪种方式,时间存储都不正确(正如您可以从1753年看到的那样),并且可能还会出现其他问题。