简体   繁体   中英

Comparing with date in Oracle sql

I have a column 'creation_date' which is of type 'date' , when I am querying my table for distinct records based on 'creation_date' I am getting 6 records:

select distinct creation_date from test_table;

output:

06-APR-11
06-APR-11
28-MAR-11
06-APR-11
06-APR-11
18-MAR-11

In this output 6th April is displayed 4 times even when I used distinct in my query. Also when I am trying to find out all records which are matching with creation_date of 6th April 2011 I am not getting any results. Below is my query:

select * from  test_table where creation_date = to_date('06-APR-11','DD-MON-YY');

Please help me where I am doing wrong in these two queries.

The problem is twofold. Firstly the dates almost definitely have time-components. to_date('06-MAR-11','DD-MON-YY') is equivalent to 2011/03/06 00:00:00 . If you use the TRUNC() function you will be able to see everything for that day:

select * 
  from test_table
 where trunc(creation_date) = to_date('06-MAR-11','DD-MON-YY');

I would not use the MON datetime format model . As I explain here it depends on your region and settings. It's safer to use a numeric month format model instead. Equally, always specify century as part of the year.

where trunc(creation_date) = to_date('06-03-YY11','DD-MM-YYYY');

Your second problem is almost definitely your NLS_DATE_FORMAT ; it appears to not take into account the time, hence why you see 4 identical dates. This only governs the manner in which data is displayed not how it is stored.

You can change this using something like:

ALTER SESSION SET NLS_DATE_FORMAT = "DD/MM/YYYY HH24:MI:SS"

If I set up a test environment using the following:

create table test_table ( creation_date date );
insert into test_table values ( sysdate );
insert into test_table values ( sysdate - 0.01 );
alter session set nls_date_format = "YYYY/MM/DD";

You can see the data returned does not include time (though SYSDATE does):

SQL> select * from test_table;

CREATION_D
----------
2013/04/12
2013/04/12

Altering the NLS_DATE_FORMAT and performing the same SELECT, you now get a time component:

SQL> alter session set nls_date_format = "YYYY/MM/DD HH24:MI:SS";

Session altered.

SQL> select * from test_table;

CREATION_DATE
-------------------
2013/04/12 12:48:41
2013/04/12 12:34:17

Lastly, when trying to select today's date alone no rows will be returned:

SQL> select *
  2    from test_table
  3   where creation_date = to_date('20130412','yyyymmdd');

no rows selected

But, when using TRUNC() to compare on only the date portion of the field you get all your rows again:

SQL> select *
  2    from test_table
  3   where trunc(creation_date) = to_date('20130412','yyyymmdd');

CREATION_DATE
-------------------
2013/04/12 12:48:41
2013/04/12 12:34:17

To actually answer your second question, if you want unique dates you can re-use the TRUNC() function:

select distinct trunc(creation_date)
  from test_table

The DATE datatype stores the year (including the century), the month, the day, the hours, the minutes, and the seconds (after midnight). You must also consider this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM