select data based on a date column - oracle

I was trying to select some data from my table using the following query:
select * from table1 where column1 = to_date('14-05-14','yy-mm-dd');
Where the column data type is DATE. I observed that, the above query won't return anything unless we modified it as,
select * from table1 where trunc(column1) = to_date('14-05-14','yy-mm-dd');
even though there are records available.
I checked the documentation for TRUNC.Can anyone please explain why this happens?
UPDATE
As per the valuable comments I think some time values may also associated with the DATE. But I cannot view/edit that time. How can I ensure there are time values associated.

Both TO_DATE and TRUNC are different. See the below example.
SQL> ALTER SESSION SET nls_date_format = 'dd/mm/yyyy hh24:mi:ss';
Session altered.
SQL> SELECT TO_DATE(SYSDATE) FROM DUAL;
TO_DATE(SYSDATE)
-------------------
28/05/2014 16:03:25
SQL> SELECT TRUNC(SYSDATE) FROM DUAL;
TRUNC(SYSDATE)
-------------------
28/05/2014 00:00:00
In Your first query to_date('14-05-14','yy-mm-dd') is comparing with the date field column1 in your table which has time values also. Whereas in Your 2nd query You are truncating the time part from table data and from Your query, that's why it's matching.

The DATE datatype stores the year (including the century), the month, the day, the hours, the minutes, and the seconds (after midnight).
TRUNC function will truncate the date to the day value, so that any hours, minutes, or seconds will be truncated off.
For more info please look at these below links
http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT413
http://www.techonthenet.com/oracle/functions/trunc_date.php

Related

Why doesn't this Oracle DATE comparison work

In Oracle 12, if I create a very simple table, TEST_TABLE, with a single varchar2(128) column 'name' and populate that column with lots of strings of '20170831', and my sysdate shows:
SELECT sysdate FROM dual;
29-SEP-17
then why does this SQL query return 0 rows:
SELECT TO_DATE(name,'YYYYMMDD'),
TO_DATE(TRUNC(SYSDATE),'DD-MM-YYYY')
FROM TEST_TABLE
WHERE TO_DATE(name,'YYYYMMDD') < TO_DATE(TRUNC(SYSDATE),'DD-MM-YYYY');
(This is a very simplified example of a problem I'm facing in my partition maintenance script and have not been able to solve for the last week).
Thank you in advance for any assistance related to the above query.
Midnight(time part is 00:00:00.000):
SELECT TO_DATE(name,'YYYYMMDD'), TRUNC(SYSDATE)
FROM TEST_TABLE
WHERE TO_DATE(name,'YYYYMMDD') <= TRUNC(SYSDATE);
You could also try:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
Just don't apply a to_date() to an already date field, this because, it will implicitly convert that date into varchar and then apply the to_date() function to it, for example your query part TO_DATE(TRUNC(SYSDATE),'DD-MM-YYYY') is interpreted like this:
TO_DATE(TO_CHAR(TRUNC(SYSDATE)),'DD-MM-YYYY')
TO_CHAR(TRUNC(SYSDATE)) is getting a char something like: '31-AUG-17', and that is not in 'DD-MM-YYYY' format.
And because of that, TO_DATE(TRUNC(SYSDATE),'DD-MM-YYYY') gets something like this: 29/09/0017 and your filter goes FALSE and gets no results.

Oracle date comparison in where clause

For eg I have a student table with a DOJ(date of joining) column with its type set as DATE now in that I have stored records in dd-mon-yy format.
I have an IN param at runtime with date passed as string and its in dd/mm/yyyy format. How do I compare and fetch results on date?
I want to fetch count of records of students who have DOJ of 25-AUG-92 per my database table student, but I am getting date as varchar in dd/mm/yyyy format in an IN param, kindly please guide.
I have tried multiple options such as trunc, to_date, to_char but, unfortunately nothing seems to work.
I have a student table with a DOJ(date of joining) column with its type set as DATE now in that I have stored records in dd-mon-yy format.
Not quite, the DATE data-type does not have a format; it is stored internally in tables as 7-bytes (year is 2 bytes and month, day, hour, minute and second are 1-byte each). The user interface you are using (i.e. SQL/PLUS, SQL Developer, Toad, etc.) will handle the formatting of a DATE from its binary format to a human readable format. In SQL/Plus (or SQL Developer) this format is based on the NLS_DATE_FORMAT session parameter.
If the DATE is input using only the day, month and year then the time component is (probably) going to be set to 00:00:00 (midnight).
I have an IN param at runtime with date passed as string or say varchar and its in dd/mm/yyyy format. How do I compare and fetch results on date.?
Assuming the time component for you DOJ column is always midnight then:
SELECT COUNT(*)
FROM students
WHERE doj = TO_DATE( your_param, 'dd/mm/yyyy' )
If it isn't always midnight then:
SELECT COUNT(*)
FROM students
WHERE TRUNC( doj ) = TO_DATE( your_param, 'dd/mm/yyyy' )
or:
SELECT COUNT(*)
FROM students
WHERE doj >= TO_DATE( your_param, 'dd/mm/yyyy' )
AND doj < TO_DATE( your_param, 'dd/mm/yyyy' ) + INTERVAL '1' DAY
The below should do what you've described. If not, provide more information on how "nothing seems to work".
-- Get the count of students with DOJ = 25-AUG-1992
SELECT COUNT(1)
FROM STUDENT
WHERE TRUNC(DOJ) = TO_DATE('25/AUG/1992','dd/mon/yyyy');
The above was pulled from this answer. You may want to look at the answer, because if performance is critical to you, there is a different way to write this query which doesn't use trunc, which will allow Oracle to use index on DOJ, if one is present.
Though I am bit late in posting this but I have been able to resolve this.
What I did was I converted both the dates to_char in similar formats and it worked here is my query condition that worked..
TO_CHAR(TO_DATE(C.DOB, 'DD-MON-YY'),'DD-MON-YY')=TO_CHAR(TO_DATE(P_Dob,'DD/MM/YYYY'),'DD-MON-YY'))
Thanks for the support all. :)

how to change the date to time in oracle 10g

I have to put in STIMING a time when I insert I use TO_DATE function but it give me date not time and it should be time.
This is the table and the code that i use
SQL> select * from shift;
SNO SNAME STIMING
---------- -------------------- ---------
121323 morning 01-APR-17
112232 evening 01-APR-17
665342 afternoon 01-APR-17
SQL> update shift
2 set STIMING= ('07:00:00 HH,MI,SS')
3 where SNO=121323;
set STIMING= ('07:00:00 HH,MI,SS')
*
ERROR at line 2:
ORA-01843: not a valid month
I have to put in STIMING a time
Oracle does not have a TIME datatype. The DATE data type is always stored internally as 7-bytes and is always composed of year (2-bytes) and month, day, hours, minutes and seconds (1-byte each).
You cannot not have a year, month or day component of a DATE.
If you want a time on its own then you will have to store it as a different data type or store the year/month/day and ignore that component.
When you are SELECTing the STIMING column it is not showing the time component. You can change this by changing the default date format which is set in the NLS_DATE_FORMAT session parameter.
You can review this parameter using:
SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT';
You can set this value within your current session using:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
(Note: this does not change the value for any other users.)
When you insert the date you can use:
INSERT INTO shift ( SNO, SNAME, STIMING)
VALUES ( 121323, 'morning', TO_DATE( '01-APR-2017 07:00' DD-MON-YYYY HH24:MI' ) )
Or, an ANSI TIMESTAMP literal (which will be implicitly cast to the DATE format of the column):
INSERT INTO shift ( SNO, SNAME, STIMING)
VALUES ( 121323, 'morning', TIMESTAMP '2017-04-01 07:00:00' )
I suggest you to avoid updates, change your insert part from to_date with no formatting param to to_date( colname, 'DD-MON-YY HH24:MI:SS')

Between not included the end date in oracle

I am writing the query like
select * from tablename where date between '27-mar-2015' and '1-apr-2015'.
but records with date '1-apr-2015' is not retrieved from the oracle database date type is TIMESTAMP(6).
between '27-mar-2015' and '1-apr-2015'
'27-mar-2015' is NOT a DATE, it is a string literal. You are forcing Oracle to do an implicit datatype conversion.
date type is TIMESTAMP(6)
Since your data type is TIMESTAMP, you need to take care of the precision of the TIMESTAMP datatype which holds fractions of a second to a precision between 0 and 9 decimal places, the default being 6.
BETWEEN
to_timestamp('27-mar-2015 01.01.01.000001','dd-mon-yyyy HH24:MI:SS.FF')
AND
to_timestamp('01-apr-2015 23.59.59.999999','dd-mon-yyyy HH24:MI:SS.FF')
For example,
SQL> ALTER SESSION SET nls_timestamp_tz_format = 'DD-MON-YYYY HH24:MI:SS.FF';
Session altered.
SQL> SELECT
2 to_timestamp('27-mar-2015 01.01.01.000001','dd-mon-yyyy HH24:MI:SS.FF') st,
3 to_timestamp('01-apr-2015 23.59.59.999999','dd-mon-yyyy HH24:MI:SS.FF') end
4 FROM dual
5 /
ST END
---------------------------------- ----------------------------------
27-MAR-15 01.01.01.000001000 AM 01-APR-15 11.59.59.999999000 PM
SQL>
You have to note that timestamp-columns (and with oracle even date-columns) always include the time of day and that date '1-apr-2015' actually means '1-apr-2015 00:00:00' - then everything makes sense. The exact string-representation of timestamps might vary according to the configured locale.
To get date including the first of april you best use between ... and '2-apr-2015' if you don't mind having the first microsecond of that day included.
Try convert to_date:
select * from tablename
where date between to_Date('27-mar-2015','dd-mm-yyy')
and to_date('1-apr-2015','dd-mm-yyyy')
I have faced same issue. Using TRUNC Date Function helped.
select * from tablename where trunc(date,'DAY') between '27-mar-2015' and '1-apr-2015'
Try to use this code:
select * from tablename where to_date(date,'DD-MON-YYYY') between '27-mar-2015' and '1-apr-2015'.

How to fetch records according to SYSTIMESTAMP using Hibernate/Oracle11g

I have a field named end_time (of type timestamp(6)) in my Oracle 11g DB. My requirement is to fetch records which are greater than current time stamp.As I work with remote DB, I need the current time of my oracle database server.
After some research I came to know that SYSTIMESTAMP returns current time stamp of machine where DB resides.
So I just put a condition like end_time > SYSTIMESTAMP, but it does not filter records. My end-time is of type timestamp(6).
Do I have to use any conversion function? How can I do it from Hibernate? Any idea?
Can you further explain on "does not filter records", are too many rows in your result or to few?
Your condition looks absolutely ok:
CREATE TABLE mytable (ts TIMESTAMP(6));
INSERT INTO mytable (ts) VALUES (TIMESTAMP '2012-12-06 17:00:00');
INSERT INTO mytable (ts) VALUES (TIMESTAMP '2012-12-06 18:00:00');
SELECT SYSTIMESTAMP FROM DUAL;
06.12.2012 17:10:38.347629000 +01:00
SELECT * FROM mytable WHERE ts > SYSTIMESTAMP;
06.12.2012 18:00:00.000000000
SELECT * FROM mytable WHERE ts < SYSTIMESTAMP;
06.12.2012 17:00:00.000000000

Resources