Date format in where clause-Oracle - oracle

I have one table where date column is having data in below format:
"7/25/2014 12:14:27 AM'. I need to fetch this date by putting in the where clause. can anyone suggest how can i do this?

Dates (stored in tables) are represented by 7 bytes - they do not have any format associated with them. If they are formatted as a string then that is the client program which you are using to access the database applying its own formatting to the date (which you can usually set via the preferences in that program).
If the "date" is stored with a format then you are not storing it as a date but storing it as a string (i.e. VARCHAR2) format.
Query - if the date is stored as a date:
SELECT *
FROM table_name
WHERE date_column = TO_DATE( '7/25/2014 12:14:27 AM', 'MM/DD/YYYY HH12:MI:SS AM' )
or, using ANSI/ISO literals:
SELECT *
FROM table_name
WHERE date_column = TIMESTAMP '2014-07-25 00:14:27'
or, if you want values which are just for a given day then:
SELECT *
FROM table_name
WHERE date_column >= DATE '2016-05-12'
AND date_column < DATE '2016-05-13'
(This will allow you to use any indexes on the date_column column.)
or, only passing a single day value (represented by the bind variable :date_value):
SELECT *
FROM table_name
WHERE date_column >= :date_value
AND date_column < :date_value + INTERVAL '1' DAY
Query - if the "date" is stored as a string:
SELECT *
FROM table_name
WHERE TO_DATE( date_as_a_string_column, 'MM/DD/YYYY HH12:MI:SS AM' )
= TIMESTAMP '2014-07-25 00:14:27'
or, just simply:
SELECT *
FROM table_name
WHERE date_as_a_string_column = '7/25/2014 12:14:27 AM'

Most likely the date format you see is the format your SQL tool (SQLplus, SQL Developer, Toad etc.) uses. Proper date columns don't have an associated date format.
To write a reliable query for selecting by date, explicitly specify the date format in your query (otherwise Oracle we use the date format from your current session):
SELECT * FROM T1
WHERE DATE_COL > TO_DATE('7/25/2014 12:14:27 AM', 'MM/DD/YYYY HH:MI:SS AM');
Any other date format will also work:
SELECT * FROM T1
WHERE DATE_COL > TO_DATE('2014-07-25 12:14:27', 'YYYY-MM-DD HH24:MI:SS');

Related

PL SQL data is in numeric format (20211023) i want to use the where clause on date column +30days

Select * from Table where date >='20210911' + 30days
the date is in numeric format and what to pull the records for a specific date +30days of specific date
Could you please help
Uh. Never store dates into any other datatype column but DATE. Now you first have to "convert" it, then do the arithmetic.
select *
from some_table
where to_date(date_column, 'yyyymmdd') > date '2021-09-11' + 30
--------
apply format mask that matches data in that column
Hope (should I say pray?) that all values represent valid dates. Nobody prevents you to store e.g. 20228579 into it, and - applying to_date to it - results in
SQL> select to_date('20228579', 'yyyymmdd') from dual;
select to_date('20228579', 'yyyymmdd') from dual
*
ERROR at line 1:
ORA-01843: not a valid month
SQL>
Once again, bad, BAD idea!
how to apply between clause ( where date_column between date '2021-09-11' and date '2021-09-11'+30
If you have an index on the column that you want to use then convert the value to a date then add 30 days to it and convert it back to a number:
SELECT *
FROM Table_Name
WHERE date_number BETWEEN 20210911
AND TO_NUMBER(
TO_CHAR(
TO_DATE(20210911, 'YYYYMMDD')
+ INTERVAL '30' DAY,
'YYYYMMDD'
)
)
If you don't have an index and want a simpler query then:
SELECT *
FROM Table_Name
WHERE TO_DATE(date_number, 'YYYYMMDD') BETWEEN DATE '2021-09-11'
AND DATE '2021-09-11' + INTERVAL '30' DAY
The best solution would be to convert your numeric column to a DATE column:
ALTER TABLE table_name ADD date_column DATE;
UPDATE table_name SET date_column = TO_DATE(date_number, 'YYYYMMDD');
ALTER TABLE table_name DROP COLUMN date_number;
Then:
SELECT *
FROM Table_Name
WHERE date_column BETWEEN DATE '2021-09-11'
AND DATE '2021-09-11' + INTERVAL '30' DAY
db<>fiddle here

Oracle: Why do I have to use TO_DATE to pull my data?

When trying to filter on EXPIRE_DATE, it seems I have to use TO_DATE. Why do I have to use TO_DATE? The EXPIRE_DATE data type in the database is ALREADY set to date. Here is the code that works.
SELECT * FROM MY_TABLE
WHERE EXPIRE_DATE >= TO_DATE('2020/01/13','yyyy/mm/dd')
AND EXPIRE_DATE <= TO_DATE('2020/04/19','yyyy/mm/dd')
I tried to use BETWEEN without TO_DATE and just use my dates but I received an error.
To recap, even though the data type for this is ALREADY date, it seems I have to use TO_DATE to pull my data when I want to filter. Is there something I am missing? Here is my error when I try filter my data without using TO_DATE.
Apart from some good answers here, I would like to tell you that you do not need TO_DATE to pull the data from your table.
You need to_date or date literal to convert the normal string to date which can be compared to the column data in your table, As the date column must be compared with the date data type variable/constant.
To convert normal string to date, You can use the following:
TO_DATE('2020/01/13','yyyy/mm/dd')
DATE '2020-01-13'
I would not recommend using NLS_DATE_FORMAT just for creating the date.
You don't need to use TO_DATE, instead you can use a DATE literal:
SELECT *
FROM MY_TABLE
WHERE EXPIRE_DATE >= DATE '2020/01/13'
AND EXPIRE_DATE <= DATE '2020/04/19'
Or, if your NLS_DATE_FORMAT session parameter matches YYYY/MM/DD then you can insert the values as strings and rely on implicit string conversion (don't do this though):
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY/MM/DD';
SELECT *
FROM MY_TABLE
WHERE EXPIRE_DATE >= '2020/01/13'
AND EXPIRE_DATE <= '2020/04/19'
But it is not good practice to rely on the NLS_DATE_FORMAT as ANY user can change their own value at ANY time so your query can randomly fail when users start changing these values.
You can use BETWEEN:
Warning: it's better to use always TO_DATE function with proper format string and avoid implicit conversions that in some occasions produces strange behaviors in the results.
Warning: all columns of type DATE have always the hour-minute-second component.
if you forget this you may have fewer records in the result.
Example:
create table my_table
(id number,
expire_date date
);
Some data:
insert into my_table values ( 4,to_date('2011-06-17 10:07:18','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (12,to_date('2010-10-01 17:43:30','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (13,to_date('2011-07-30 08:38:34','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (21,to_date('2010-04-22 07:03:35','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (26,to_date('2011-03-26 02:07:57','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (35,to_date('2010-09-16 17:40:01','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (38,to_date('2011-11-05 17:27:45','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (44,to_date('2011-12-25 04:51:24','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (45,to_date('2011-11-05 03:08:51','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (54,to_date('2011-09-22 18:29:14','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (78,to_date('2010-03-12 20:23:21','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (79,to_date('2011-05-19 17:30:15','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (83,to_date('2011-11-15 10:04:58','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (96,to_date('2011-03-11 20:14:30','yyyy-mm-dd hh24:mi:ss'));
Set default date format to ISO-8601 international format:
alter session set nls_date_format='YYYY-MM-DD HH24:MI:SS';
Query using implicit conversion:
SELECT a.*
fROM my_table a
where expire_date between '2010-01-01 00:00:00'
and '2010-12-31 23:59:59';
Answer:
ID EXPIRE_DATE
12 2010-10-01 17:43:30
21 2010-04-22 07:03:35
35 2010-09-16 17:40:01
78 2010-03-12 20:23:21
but using US date format month-day-year:
SELECT a.*
fROM my_table a
where expire_date between '01/01/2010 00:00:00'
and '12/31/2010 23:59:59';
You got error:
ORA-01861: literal does not match format string
Change session date format to US format:
alter session set nls_date_format='MM-DD-YYYY HH24:MI:SS';
you can write dates in US format:
SELECT a.*
fROM my_table a
where expire_date between '01/01/2010 00:00:00'
and '12/31/2010 23:59:59';
And the answer is:
ID EXPIRE_DATE
---------- -------------------
12 10-01-2010 17:43:30
21 04-22-2010 07:03:35
35 09-16-2010 17:40:01
78 03-12-2010 20:23:21

Facing issue with date function

I am trying to get the value from dba_scheduler_job_run_details view.
where log_date > (SYSDATE - 5/(24*60)) (i.e. data of last 5 mins)
But it is not providing me with the correct value.
For sample please find the data below:
SQL Query:
SELECT SYSDATE, SYSDATE - 5/(24*60),LOG_DATE,TRUNC(LOG_DATE),TO_CHAR(LOG_DATE,'YYYY/MM/DD HH:MI:SS')
FROM dba_scheduler_job_run_details
WHERE LOG_DATE > (SYSDATE - 5/(24*60))
ORDER BY LOG_DATE DESC;
o/p:
image attached
This is because log_date is timestamp with timezone datatype and when you are joining it with date datatype it will lead to two different times when Oracle does an implicit conversion to compare:
SQL> SELECT SYSTIMESTAMP, CAST(SYSDATE AS TIMESTAMP WITH TIME ZONE) time_with_tz FROM dual;
SYSTIMESTAMP TIME_WITH_TZ
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
19-MAR-18 09.57.07.654161 AM -04:00 19-MAR-18 09.57.07.000000 AM +05:30
So if I execute you query from time zone with offset +5:30 on a server with offset -4:00, Oracle will convert the SYSDATE - 5/(24*60) to sysdate - (9:30 + 0:05).
Tell Oracle to convert log_date to date explicitly and then apply the filer of > (SYSDATE - 5/(24*60) as follows and you will be fine:
SELECT SYSDATE, SYSDATE - 5/(24*60),LOG_DATE,TRUNC(LOG_DATE),TO_CHAR(LOG_DATE,'YYYY/MM/DD HH:MI:SS')
FROM dba_scheduler_job_run_details
WHERE cast(LOG_DATE AS DATE) > (SYSDATE - 5/(24*60))
ORDER BY LOG_DATE DESC;
Update: This query may have performance issue due to following reasons,
1) Oracle will convert datatype for each row for column LOG_DATE from
timestamp with time zone to date.
2) The build in index on column LOG_DATE, if any, will not be used due
to the CAST function.
Better solution is to convert the sysdate - 5/(24*60) to timestamp with time zone, you must be aware of the timezone of your Oracle server, assuming that the server is located in UTC -4:00, below query should work fine:
SELECT SYSDATE, SYSDATE - 5/(24*60),LOG_DATE,TRUNC(LOG_DATE),TO_CHAR(LOG_DATE,'YYYY/MM/DD HH:MI:SS')
FROM dba_scheduler_job_run_details
WHERE LOG_DATE > TO_TIMESTAMP_TZ (to_char(SYSDATE - 5/(24*60), 'YYYY-MM-DD HH24:MI:SS') || ' -4:00', 'YYYY-MM-DD HH24:MI:SS TZH:TZM')
ORDER BY LOG_DATE DESC;
Another easier approach as suggested by #mathguy, use INTERVAL function:
SELECT SYSDATE, SYSDATE - 5/(24*60),LOG_DATE,TRUNC(LOG_DATE),TO_CHAR(LOG_DATE,'YYYY/MM/DD HH:MI:SS')
FROM dba_scheduler_job_run_details
WHERE LOG_DATE > SYSTIMESTAMP - INTERVAL '5' MINUTE
ORDER BY LOG_DATE DESC;

Oracle query not giving result for current_date

What is the query in Oracle to fetch the data for current_date
the column end_date is like the following
end_date
27-10-16 03:35:00.000000000 PM
23-11-16 11:15:00.000000000 AM
02-11-16 03:00:00.000000000 PM
08-11-16 09:00:00.000000000 AM
Like I am running the following query as
Select * from table1
where end_date < TO_DATE('2017-04-11 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
it is running successfully, but when i replace the query with the current date ... it is not giving the results
Select * from table1
where end_date < TO_DATE(current_date, 'YYYY-MM-DD HH24:MI:SS')
could someone tell me what is the cause the second query is not giving results.
CURRENT_DATE returns date. There is no need to use TO_DATE. The below query should be enough.
Select * from table1
where end_date < current_date;
If you run the below query you'll understand what went wrong for you. Year becomes 0011.
SELECT TO_DATE(current_date, 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;
Please note that CURRENT_DATE returns the current date in the session time zone. SYSDATE returns the current date and time set for the operating system on which the database resides. This means that CURRENT_DATE and SYSDATE can return different results. You can have a look at this
The query worked like this :
Select * from table1
where trunc(end_date) < trunc(sysdate)
Trunc is used to compare the both dates and it fetch the results.
CURRENT_DATE is already a DATE value. You can format the output using to_char if you want.
end_date < CURRENT_DATE should do the job. Or you can set the nls parameter accordingly for a better readability.
If you are comparing only date, without timestamp, you can go with trunc()

Inserting timestamp in oracle timestamp column

I have a table in which there is a column with datatype TIMESTAMP(0)
When I insert a date into this column using
INSERT INTO TEST_TIMESTAMP VALUES(SYSDATE)
it inserts a date in the following example format
12-SEP-12 10.31.19.000000000 AM
I want to know how the below timestamp formats can be inserted in the table
12-SEP-12 10.31.19 and 12-SEP-12 10.31.19 AM
I tried specifying some formats using TO_CHAR while inserting SYSDATE into the table, but it didn't work.
Please suggest.
when you store a TIMESTAMP it will always store the data at maximum precision (with fractional seconds).
I think what you want to do is supply a format to display the date when you retrieve it from the database.
You can do this like so:
select to_char(timestampColumnName,'DD-MON-YY HH24:MI:SS') "Date" from test_timestamp
or
select to_char(timestampColumnName,'DD-MON-YY HH:MI:SS AM') "Date" from test_timestamp
You can return it very easy like:
SELECT to_char(sysdate,'DD-MON-YY HH24:MI:SS') FROM DUAL;
In your case use:
INSERT INTO TEST_TIMESTAMP(column_name) VALUES(to_char(sysdate,'DD-MON-YY HH24:MI:SS'));
You were missing the extra ().
INSERT INTO TEST_TIMESTAMP
VALUES (TO_TIMESTAMP('12-SEP-12 10.31.19', 'DD-MON-YY HH.MI.SS'));
INSERT INTO TEST_TIMESTAMP
VALUES (TO_TIMESTAMP('12-SEP-12 10.31.19 AM', 'DD-MON-YY HH.MI.SS AM'));
TO_CHAR(SYSDATE, 'DD/MM/YYYY HH24:MI:SS')
This for colum type insert over mode to_char.

Resources