How to use round and trunc to get dd:mm:yy:hh - sql

I am using oracle 11g and I have normal timestamps (starttime) which produce an output as follows:
23.09.14 05:15:00,000000000
Now I want an output like
23.09.14 05
Also ok would be:
23.09.14 05:00:00,000000000
but when I use something like
round(starttime, 'HH') or trunc(starttime ,'HH24') I always get
23.09.14
with no hours at all.
Looking around here at stackoverflow I found
substr(TO_CHAR(starttime),0,LENGTH(TO_CHAR(starttime))-13)
which produces the correct output as char but when I want to sort dates it wont work because it sorts alphabetically. (so for example, 1.3., 1.4, 1.5.... instead of 1.3., 2.3., 3.3,...),
Any idea how I can get a timestamp which is rounded to the full hour?
I will have to use the statement in a group by clause. The complete statement would look like:
select round(starttime, 'HH24'), sum(counter) from wmsconsolidationorderdwct group by round(starttime, 'HH24') order by round(starttime, 'HH24') desc;
So I cannot display the rounded time and sort by the full timestamp since this would violate the group by clause.

This will truncate to the hour:
trunc(SYSTIMESTAMP) + extract(hour from SYSTIMESTAMP)/24
Edit:
I just tried it and
SELECT TRUNC(SYSTIMESTAMP ,'HH24') FROM DUAL;
returns the correct result.
Fiddle

If your purpose is to display, then use TO_CHAR with desired format model.
For example,
SQL> SELECT TO_CHAR(SYSTIMESTAMP, 'DD.MM.YY HH24') FROM dual;
TO_CHAR(SYS
-----------
28.05.15 15
SQL>
If your purpose is to do date arithmetic then you need to leave the data type as date.
For example,
SQL> alter session set nls_date_format='DD-MM-YYYY HH24:MI:SS'
2 /
Session altered.
SQL> SELECT TRUNC(SYSTIMESTAMP ,'HH24') FROM DUAL
2 /
TRUNC(SYSTIMESTAMP,
-------------------
28-05-2015 15:00:00
SQL>

If you have a timestamp object:
select my_number from(
SELECT TO_NUMBER(TO_CHAR(TO_DATE (TO_CHAR (SYSTIMESTAMP, 'DD.MM.YY HH24:MI'),
'DD.MM.YY HH24:MI'
),'HH24')) AS my_number
FROM DUAL)
order by 1
This could be simplified to:
select my_number from(
SELECT TO_NUMBER(TO_CHAR(SYSTIMESTAMP, 'HH24')) AS my_number
FROM DUAL)
order by 1

Related

STRING DATE AND TIME COMBINE AND MAKE FULL DATE TIME IN ORACLE PL/SQL

I am trying to make date and time from the oracle select query as follows.
SELECT TO_CHAR(TO_DATE('230201'||''||'1529', 'YYMMDD HH24MI') , 'YYYY-MM-DD HH24:MI') FROM DUAL;
It returns the below result and it's OK.
2023-02-01 15:29
But when I try the same query with 23 or less minutes It returns the wrong result
SELECT TO_CHAR(TO_DATE('230201'||''||'1523', 'YYMMDD HH24MI') , 'YYYY-MM-DD HH24:MI') FROM DUAL;
2302-01-15 23:00
Where is the Wrong point of my query?
That's because you used wrong format model. There's no space between date and time component:
SQL> select to_char(to_date('230201' ||''|| '1523', 'yymmddhh24mi'), 'yyyy-mm-dd hh24:mi') result
2 from dual; ----
here
RESULT
----------------
2023-02-01 15:23
SQL>

Oracle Query to fetch data based on only time condition

I need to fetch the data for last six month based on when modified date but the records I need are having time greater than 1500H. Please assist.
I have tried below condition in my script but it's not working:
AND WHENMODIFIEDDATE >= to_date('2021-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
AND WHENMODIFIEDDATE <= to_date('2021-06-01 23:59:59','YYYY-MM-DD HH24:MI:SS')
AND WHENMODIFIEDDATE >= to_date('15:00:00', 'HH24:MI:SS') ;
Data Type for column WHENMODIFIEDDATE: DATE
Sample Data:
AUDITORKEY AUDITORID AUDITORNAME STATUS WHENMODIFIEDDATE
9266165 xyz xyz A 2020-10-21 08:13:43.0
The phrase
AND WHENMODIFIEDDATE >= to_date('15:00:00', 'HH24:MI:SS')
does not look at hours. If you use the TO_DATE command on just a time component, we will automatically construct a FULL date, eg
SQL> alter session set nls_date_format = 'dd/mm/yyyy hh24:mi:ss';
Session altered.
SQL> select to_date('15:00:00', 'HH24:MI:SS') from dual;
TO_DATE('15:00:00',
-------------------
01/08/2021 15:00:00
This is why your third predicate is having no effect (or could easily have the wrong effect depending on your date criteria).
As others mentioned in the comments, if you want to get just the HOUR from a date, you can use options such as EXTRACT or TO_CHAR depending on the data type of the source column
SQL> create table t ( x timestamp , y date) ;
Table created.
SQL> insert into t values (localtimestamp, sysdate);
1 row created.
SQL> select extract(HOUR from x) from t;
EXTRACT(HOURFROMX)
------------------
11
SQL> select extract(HOUR from y) from t;
select extract(HOUR from y) from t
*
ERROR at line 1:
ORA-30076: invalid extract field for extract source
SQL> select to_number(to_char(y,'HH24')) from t;
TO_NUMBER(TO_CHAR(Y,'HH24'))
----------------------------
11

Oracle query on time (and not date)

How can you query on just the time portion of an Orace date field. Ie:
select * from mytable
where
date_column < '05:30:00'
Want the query to return any rows where the time represented by date_column is less than 5:30 regardless of the date.
You can try like this:
select * from mytable
where
to_char( date_column, 'HH24:MI:SS' ) < '05:30:00'
You can see how far the date is from midnight, and filter on that:
select * from mytable
where date_column - trunc(date_column) < 5.5/24
The date_column - trunc(date_column) calculation will give you a fraction of a day, as is normal for date arithmetic. The 5.5/24 is the fraction of the day represented by the time at 05:30; 5.5 hours out of 24 hours.
If the column was a timestamp instead of a date you'd see an interval data type as the result of the subtraction. You can use an interval literal anyway if you prefer or find it easier to understand than 5.5/24 (or have more complicated times to compare, which are harder to express as a fraction):
select * from mytable
where date_column < trunc(date_column) + interval '0 05:30:00' day to second;
This way round you're comparing the date in your column with the truncated date (i.e. midnight on that day) with 5 hours 30 minutes added to it, which is 05:30 the same day.
Quick demo with simple data in a CTE, and a third very slight variant, but they all get the same result:
with mytable (date_column) as (
select to_date('2016-04-15 05:29:29', 'YYYY-MM-DD HH24:MI:SS') from dual
union all select to_date('2016-04-14 05:29:29', 'YYYY-MM-DD HH24:MI:SS') from dual
union all select to_date('2016-04-15 05:30:30', 'YYYY-MM-DD HH24:MI:SS') from dual
)
select * from mytable
where date_column < trunc(date_column) + 5.5/24;
DATE_COLUMN
-------------------
2016-04-15 05:29:29
2016-04-14 05:29:29
Note though that any manipulation of the column like this will prevent an index being used. If you have to do this regularly it might be worth adding a virtual column/index which does that calculation.
You need to cast the time back to date, otherwise you're simply doing string comparison.
Oracle doesn't really have a clever way of doing this. Simplest to cast both dates to the same day and do the comparison.
I.e.
select *
from mytable
where to_date ('01.01.2000 ' || to_char (date_column, 'hh24:mi:ss'), 'dd.mm.yyyy hh24:mi:ss') <
to_date ('01.01.2000' || '05:30:00', 'dd.mm.yyyy hh24:mi:ss')

Insert date in oracle

When i executed the below query in Oracle
select TO_CHAR((CURRENT_DATE),'DD-Mon-YYYY HH24:MI:SS') from dual;
O/P : 04-Mar-2014 14:25:14
I would like to select current date only without current time as below
select TO_CHAR(trunc(CURRENT_DATE),'DD-Mon-YYYY HH24:MI:SS') from dual;
O/P : 04-Mar-2014 00:00:00
To achieve the only way is to apply function trunc() on the query? Is there any another way?
Edit : Thanks for your ans.Can it be done without any function?(wihout using to_char or trunc)
{sorry for missing this info}
The answer is simply no, there is no function that only gets the date part of the date / time (even current_date or sysdate are functions after all).
You should always use trunc to get the current date, without the time.
It isn't necessary to do a trunc and a to_char together. Keep to_char and don't specify the time part.
This is sufficient:
To get the date as varchar:
select TO_CHAR(CURRENT_DATE,'DD-Mon-YYYY') from dual
To get the date as date, with the time part as 00:00:00:
select trunc(CURRENT_DATE) from dual
You can do this:
select TO_CHAR(CURRENT_DATE,'DD-Mon-YYYY')||' 00:00:00' from dual;
there is also EXTRACT function which can be used like that:
SELECT extract(DAY FROM sysdate)
||'-' ||
extract(MONTH FROM sysdate)
|| '-' || extract(YEAR FROM sysdate)
FROM dual;
result: 4-3-2014
Use This Query...
select (TO_CHAR(TRUNC(CURRENT_DATE),'DD-Mon-YYYY HH24:MI:SS')) from dual

Oracle Timestamp Conversion with Dates

Assuming this has a simple solution, but I can't find it.
I'm trying to do some logic on a DATE field in Oracle. My desire is to take a DATE field and subtract X hours from it.
For instance: SELECT A.MyDATE - 100 Hours from dual;
however, I need a result in a timestamp format 'YYYY-MM-DD hh:mm'.
I've tried CAST(A.MyDATE as TIMESTAMP) - NUMTODSINTERVAL(100/24,'day') however it didn't work.
I found out that the issue is that the MyDATE field when cast to a timestamp still contained some residual time elements. How can I reset these??
Thanks!
You can just do this with subtraction:
select a.MyDate - 100.0/24
To convert to varchar:
select to_char(a.MyDate - 100.0/24, 'YYYY-MM-DD')
And, if you want to get rid of that pesky time on the date:
select trunc(a.MyDate - 100.0/24) as JustTheDate
The formats and dates in my example can be changed to any other formats and dates:
SELECT To_Timestamp(To_Char(Sysdate - INTERVAL '100' HOUR, 'MM/DD/YYYY HH24:MI'), 'MM/DD/YYYY HH24:MI')
FROM dual
/
Output:
2/4/2013 10:18:00.000000000 AM
To remove time element add Trunc() to any of your dates...:
SELECT Trunc(To_Timestamp(To_Char(Sysdate - INTERVAL '100' HOUR, 'MM/DD/YYYY HH24:MI'), 'MM/DD/YYYY HH24:MI'))
FROM dual
/
Output: 2/4/2013
Conversion/Casting - when using other dates in place of sysdate then add formats as in my other examples:
SELECT CAST(SYSDATE AS TIMESTAMP) - INTERVAL '100' HOUR FROM dual
/
Output: 2/4/2013 10:26:35.000000000 AM
SELECT start_date tstamp_to_date, CAST(start_date AS timestamp) date_to_tstamp FROM
(
SELECT to_date(to_char(to_timestamp ('2013-02-07 10:07:47.000' , 'YYYY-MM-DD HH24:MI:SS.FF'),'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS') start_date
FROM dual
)
/
Output:
tstamp_to_date date_to_tstamp
-------------------------------------------------------
2/7/2013 10:07:47 AM 2/7/2013 10:07:47.000000 AM
In Oracle, a DATE always has a day and a time component. Depending on the tool you are using and your session's NLS_DATE_FORMAT, it is entirely possible that the tool may not display the time component when you look at the data. But that is simply a display question, it has no impact on the actual data.
If you want to subtract 100 hours from midnight on the day that MyDate represents
SELECT TRUNC(MyDate) - interval '100' hour
FROM dual
This will return a DATE. If you want to return a string in a particular format
SELECT TO_CHAR( TRUNC(MyDate) - interval '100' hour, 'YYYY-MM-DD hh:mi am' )
FROM dual
Note that I'm assuming that there was a typo in your question. I assume that you want to display the minutes after the hour (mi) rather than the month (mm).
I am trying to fetch the records which is older than 30 days (from Mod_date) and I am using the below query and it is returning all the data and I want only 30 days old data.
Sample :- Mod_date 03-NOV-12 12.00.00.000000000 AM
Query :-
select Mod_date from fil_cnfact where Mod_date <= sysdate -30 order by Mod_date asc ;