我的TO_DATE似乎无法正常运行

时间:2020-10-04 19:56:42

标签: sql oracle to-date

因此,我试图获取该部分的ID和该部分于2007年2月10日注册的学生人数。该查询应返回6行时不返回任何结果。

其日期格式已经是DD-MON-YY。

这是我到目前为止的内容: 我从另一个查询中提取了TO_DATE,并且可以正常运行。没有它,查询就可以工作,因此请确定它与TO_DATE有关

SELECT section_id, COUNT(student_id) "ENROLLED"
FROM enrollment
WHERE enroll_date = TO_DATE('2/10/2007', 'MM/DD/YYYY')
GROUP BY section_id
ORDER BY ENROLLED;

2 个答案:

答案 0 :(得分:1)

最可能的问题是,您没有考虑到小数部分。您可以通过截断查询中的列来忽略该小数日期部分:

SELECT section_id, COUNT(student_id) "ENROLLED"
FROM enrollment
WHERE TRUNC(enroll_date) = TO_DATE('2/10/2007', 'MM/DD/YYYY')
GROUP BY section_id
ORDER BY ENROLLED;

我假设列enroll_date的数据类型为DATE。

一些解释:Oracle按照here的描述存储日期,当您声明“其日期格式已经是DD-MON-YY”时,它不存储日期。这只是您看到日期的格式,该格式由会话的参数NLS_DATE_FORMAT确定。

让我们使用测试表进行快速测试。创建表并在我的会话中检查NLS_DATE_FORMAT。

create table DATE_TST 
( id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
  test_date DATE
);

INSERT INTO date_tst (test_date) VALUES (SYSDATE);

SELECT value
FROM   nls_session_parameters
WHERE  parameter = 'NLS_DATE_FORMAT';

DD-MON-YYYY

这就是我看到日期的方式。


SELECT * FROM date_tst;

04-OCT-2020

所以我有今天的约会。凉。现在让我们看看是否可以使用该日期进行查询:


SELECT * FROM date_tst WHERE test_date = TO_DATE('04-OCT-2020','DD-MON-YYYY');

no rows.

没有显示行,因为我获取日期的日期格式没有时间成分。 DATE有年,月,日,小时,分钟和秒。该格式仅包含年,月和日。让我们查询数据以检查是否存在时间分量。

SELECT TO_CHAR(test_date,'DD-MON-YYYY HH24:MI:SS') FROM date_tst;

4-OCT-2020 21:12:39

是的。。。SYSDATE是当前时间,直到秒。现在,以更精确的日期格式再次尝试该查询:

SELECT * FROM date_tst WHERE test_date = TO_DATE('04-OCT-2020 21:12:39','DD-MON-YYYY HH24:MI:SS');

04-OCT-2020

这是我们的行。 TRUNC命令将切断时间部分:

SELECT TO_CHAR(TRUNC(test_date),'DD-MON-YYYY HH24:MI:SS') FROM date_tst;

04-OCT-2020 00:00:00

因此您可以简化查询:

SELECT * FROM date_tst WHERE TRUNC(test_date) = TO_DATE('04-OCT-2020','DD-MON-YYYY');

04-OCT-2020

答案 1 :(得分:0)

TO_DATE('2/10/2007', 'MM/DD/YYYY')给您一个午夜的约会;但是,这只会在那一刻匹配值。您需要做的是:

  • TRUNC将列中的日期设置为午夜,以使您的值匹配(但是,这将阻止您在列上使用索引,并且需要使用基于函数的索引);或
  • 一个更好的解决方案是使用一个日期范围,该日期范围从您要匹配的当天的午夜开始,一直到第二天的午夜,但不包括在内。

您可以使用TO_DATE或日期文字来完成此操作:

SELECT section_id,
       COUNT(student_id) "ENROLLED"
FROM   enrollment
WHERE  enroll_date >= DATE '2007-02-10'
AND    enroll_date <  DATE '2007-02-11'
GROUP BY section_id
ORDER BY ENROLLED;

顺便说一句:

其日期格式已经为DD-MON-YY

假设enroll_date列具有DATE数据类型,则它没有格式;它是一种二进制数据类型,由7个字节组成(世纪,世纪,月,日,小时,分钟和秒)。

您看到的是default date format用户界面在向用户显示二进制日期值时适用,您可以使用以下方式进行更改:

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';

(或您想要的任何格式。)

这不会更改存储在列中的二进制数据。

相关问题