sqlplus set explicit time - sql

I am using the following query to extract data. But, I want the time to be exact instead of variable.
WHERE DAILY_OPEN_POSITIONS.REPORT_TIMESTAMP <= SYSTIMESTAMP - INTERVAL '3' HOUR + INTERVAL '1' MINUTE
AND DAILY_OPEN_POSITIONS.REPORT_TIMESTAMP >= SYSTIMESTAMP - INTERVAL '3' HOUR - INTERVAL '1' MINUTE
I want the time to be given like this:
where REPORT_TIMESTAMP BETWEEN '2016-08-11 20:59:00' AND '2016-08-11 20:59:01'
The time is a constant, but the date always points to yesterday, that's why I used the first query. is there anyway to mix both?

Time stamp between yesterday's date, time between 20:59:00 and 20:59:01.
Functions used: to_timestamp , to_char , sysdate
where REPORT_TIMESTAMP BETWEEN
TO_TIMESTAMP (to_char(sysdate-1,'DD-Mon-RR') || ' 20:59:00', 'DD-Mon-RR HH24:MI:SS')
and
TO_TIMESTAMP (to_char(sysdate-1,'DD-Mon-RR') || ' 20:59:01', 'DD-Mon-RR HH24:MI:SS')

Related

PostgreSQL BigInt to DateTime and Add hours to get local time

I am trying to convert the bigint value to date in PostgreSQL
I am using the below code
SELECT TO_CHAR(TO_TIMESTAMP(1564983632051/ 1000),
'YYYY-MM-DD HH24:MI:SS')
then its returning 2019-08-05 07:40:32, which is correct.
However i want to add few hours to it to get local time. Tried with the following query but its throwing an error :
SELECT TO_CHAR(TO_CHAR(TO_TIMESTAMP(1564983632051/ 1000),
'YYYY-MM-DD HH24:MI:SS') + INTERVAL '4 hour')
I do not want to use a separate query, if that's the case i can use
select (to_timestamp('2019-08-05 07:40:32', 'YYYY-MM-DD HH24:MI:SS.US') + interval '4 hour')::timestamp;
this will return the desired output.
I need both conversion and hours addition in a single query.
You should add to TIMESTAMP portion, not to portion casted to CHAR :
SELECT TO_CHAR(
TO_TIMESTAMP(1564983632051/ 1000)+ INTERVAL '4 hour',
'YYYY-MM-DD HH24:MI:SS'
)
The problem is here:
select pg_typeof(TO_CHAR(TO_TIMESTAMP(1564983632051/ 1000), 'YYYY-MM-DD HH24:MI:SS'));
pg_typeof
-----------
text
Adding an interval to a text value is not going to work.
So something like:
select TO_CHAR(TO_TIMESTAMP(1564983632051/1000) + interval '4 hour', 'YYYY-MM-DD HH24:MI:SS') ;
to_char
---------------------
2019-08-05 02:40:32
It is best to stay in a type for operations until the very end. Then apply formatting.

CAST(CURRENT_TIMESTAMP AS TIME)

i am trying to work with timestamps and manipulate the data out of them so i can measure different things in our database.
currently i have a column that holds a "DATE" but in fact contains a whole stamp 'DD/MM/YYYY HH24:MI:SS'
i want to be able to grab all entries where "DTIME" between "09:00" and "09:15" however have not been able to cast it correctly.
If i was to output the column without any conversion it would look like this
SELECT ia.DTIME3
FROM ISIS_AUDIT ia
WHERE ia.DTIME3 like to_date('24/01/2019', 'DD/MM/YYYY');
OUTPUT: 24/JAN/19
if i was to convert it to_char,
SELECT to_char(ia.DTIME3, 'DD/MM/YYYY HH24:MI:SS')
FROM ISIS_AUDIT ia
WHERE ia.DTIME3 like to_date('24/01/2019', 'DD/MM/YYYY');
OUTPUT: 24/01/2019 07:10:52
I want to be able to take this DTIME3 and find entries between the times but CAST and CONVERT to TIME doesnt work.
This is my working option but it outputs the date still and i dont want to have to specify the date so it can be run across any day of the week.
WHERE ia.DTIME3 between to_date('24/01/2019 09:00:00', 'DD/MM/YYYY HH24:MI:SS') and to_date('24/01/2019 09:15:00', 'DD/MM/YYYY HH24:MI:SS');
OUTPUT: 24/01/2019 09:00:01
currently i have a column that holds a "DATE" but in fact contains a whole stamp 'DD/MM/YYYY HH24:MI:SS'
That's what Oracle DATE datatype does : storing a date and time (without fractional seconds, that belong to the TIMESTAMP datatypes). There is no specific format in Oracle for date only (without time).
To filter on the time of the day, you can use the TO_CHAR() function to convert your date to a string that represents its time, and that you can compare :
TO_CHAR(ia.DTIME3, 'hh24:mi') BETWEEN '09:00' AND '09:14'
You can also CAST the date to a timestamp and use the EXTRACT() function :
EXTRACT(HOUR FROM CAST(ia.DTIME3 AS TIMESTAMP)) = 9
AND EXTRACT(MINUTE FROM CAST(ia.DTIME3 AS TIMESTAMP)) < 15
Oracle has DATE and TIMESTAMP data types; both have year, month, day, hour, minute, second components (TIMESTAMP also has fractional seconds). Oracle does not have a TIME data type.
Instead, use TRUNC() to truncate the time component to midnight and add an interval literal:
SELECT *
FROM ISIS_AUDIT
WHERE DTIME BETWEEN TRUNC( DTIME ) + INTERVAL '09:00' HOUR TO MINUTE
AND TRUNC( DTIME ) + INTERVAL '09:15' HOUR TO MINUTE;
and ia.DTIME1 not between to_date('&&S_DATE 08:50:00', 'DD/MM/YYYY HH24:MI:SS') and to_date('&&S_DATE 09:20:00', 'DD/MM/YYYY HH24:MI:SS')
and ia.DTIME1 not between to_date('&&S_DATE 11:50:00', 'DD/MM/YYYY HH24:MI:SS') and to_date('&&S_DATE 12:40:00', 'DD/MM/YYYY HH24:MI:SS')
and ia.DTIME3 not between to_date('&&S_DATE 08:50:00', 'DD/MM/YYYY HH24:MI:SS') and to_date('&&S_DATE 09:20:00', 'DD/MM/YYYY HH24:MI:SS')
and ia.DTIME3 not between to_date('&&S_DATE 11:50:00', 'DD/MM/YYYY HH24:MI:SS') and to_date('&&S_DATE 12:40:00', 'DD/MM/YYYY HH24:MI:SS')
i was trying to do this way however i noticed if i have a start time of 08:30 and a finish time of 09:30 then it falls between 09:00 and 09:15 so i want to exclude it from the table. the current WHERE clause im using is quite specific and will only exclude if the timestamp contains the values specified.
Really it would want to read "DTIME1 to DTIME3 not between 09:00 and 09:15"

Select rows within last complete minute

I want to find rows in my database which have a timestamp within the last complete minute.
For example:
When it is 12:02:43 --> from 12:01:00 to 12:01:59 (inclusive)
When it is 14:01:00 --> from 14:00:00 to 14:00:59 (inclusive)
When it is 16:24:59 --> from 16:23:00 to 16:23:59 (inclusive)
I found the following statement.
select *
from table
where time < to_date(to_char(sysdate, 'DD.MM.YYYY HH24:MI'), 'DD.MM.YYYY HH24:MI')
and time >= to_date(to_char(sysdate - numtodsinterval(1, 'Minute'), 'DD.MM.YYYY HH24:MI'), 'DD.MM.YYYY HH24:MI')
The statement works, but converting the date to a string and then back to a date seems a little weird. Is there any other method to use only minutes as precision (without seconds)?
Oracle-specific functions could be used, but I'd prefer a standard SQL way.
You can use TRUNC(SYSDATE,'MI') -> TRUNC('12:02:43','MI') = 12:02.
Or you can use this select extract(MINUTE from current_timestamp) from dual;
You can truncate timestamps (and dates) to the nearest minute - so you can use TRUNC( SYSTIMESTAMP, 'MI' ) to round to the start of the current minute and subtract INTERVAL '1' MINUTE to get the start of the previous minute:
select *
from table_name
where time >= TRUNC( SYSTIMESTAMP, 'MI' ) - INTERVAL '1' MINUTE
and time < TRUNC( SYSTIMESTAMP, 'MI' )
You are right, converting it to string an back seems unnecessary. I'd leave it as a date. How about:
SELECT *
FROM t
WHERE t BETWEEN TRUNC(SYSDATE,'MI')
AND TRUNC(SYSDATE,'MI')+1/24/60/60*59;
TRUNC(...,'MI') chops of the seconds, for instance
SELECT trunc(sysdate,'MI'), TRUNC(SYSDATE,'MI')+1/24/60/60*59 from dual;
returns
2018-06-06 11:04:00 2018-06-06 11:04:59
EDIT: As David Faber pointed out, this works only if your column has the datatype DATE. For the datatype TIMESTAMP, you're better of with #MT0's solution.

Last date with time of the month

Need your help to conclude the query to fetch last date time of the sysdate month.
select to_char(last_day(sysdate),'DD-Mon-YYYY HH24:MI:SS') from dual
it gives last date as expected, but I need time as 23:59:00 which is not possible thru above query.
You could use TRUNC on next day i.e. SYSDATE + 1, and then subtract 60 seconds i.e. 60/86400 to get the desired output.
SQL> SELECT to_char((trunc(last_day(sysdate)) +1) - 60/86400,'DD-Mon-YYYY HH24:MI:SS') dt
2 FROM dual;
DT
--------------------
29-Feb-2016 23:59:00
SQL>
You could also use interval '1' minute or interval '60' second instead of 60/86400.
If you just want it for display for some reason you can hard-code the time into the format mask:
select to_char(last_day(sysdate), 'DD-Mon-YYYY "23:59:00"') from dual;
But you probably really want it as a date object, in which case you can add 23 hours and 59 minutes to the truncated (midnight) date, wchi is 1439 of the 1440 minutes in a day:
select to_char(trunc(last_day(sysdate)) + 1439/1440, 'DD-Mon-YYYY HH24:MI:SS')
from dual;
Or you can go to the next day and remove a minute, either with fractional days or with intervals:
select to_char(trunc(last_day(sysdate)) + interval '1' day - interval '1' minute,
'DD-Mon-YYYY HH24:MI:SS') from dual;
Generally if you're working with time periods you want to include up to 23:59:59, which you can also do with any of those methods, but as Damien_The_Unbeliever said in a comment, it's easier to compare against the start of the next period (e.g. < add_months(trunc(sysdate, 'MM'), 1). It's easy to accidentally miss part of a day by not taking the time into account properly, particularly if you actually have a timestamp rather than a date.

Using "Interval" in Oracle where "Interval" is a value from a table

I need to generate a list of values in an Oracle DB with the following columns of data:
ITEM_TYPE VARCHAR2(20)
ITEM_LAST_UPDATED DATE
ITEM_UPDATE_TOLERANCE NUMBER(1)
The only data that should be send out to the console would be items that have the date in 'ITEM_LAST_UPDATED' less than the sysdate minus the integer value within 'ITEM_UPDATE_TOLERANCE'.
So, if I wanted to just show the ones that were one hour past due, I can do:
select ITEM_TYPE from MY_TABLE
where
to_char(ITEM_LAST_UPDATED, 'DD-MON-YYYY HH24:MI')
<=
to_char(sysdate - interval '1' hour, 'DD-MON-YYYY HH24:MI');
However, rather than using the '1' in the above statement, I need to replace it with the numeric value of ITEM_UPDATE_TOLERANCE.
I tried several different versions, but all error (such as):
select ITEM_TYPE from MY_TABLE
where
to_char(ITEM_LAST_UPDATED, 'DD-MON-YYYY HH24:MI')
<=
to_char(sysdate - interval to_number(ITEM_UPDATE_TOLERANCE) hour, 'DD-MON-YYYY HH24:MI');
Why are you converting a perfect DATE column to a character value just to compare it another DATE value converted to a character column.
Simply use:
ITEM_LAST_UPDATED <= sysdate - interval '1' hour
To achieve what you want, just multiply the value:
ITEM_LAST_UPDATED <= sysdate - (interval '1' hour) * ITEM_UPDATE_TOLERANCE
There is also absolutely no need to convert a number to a number using the to_number() function.
As an alternative to #a_horse_with_no_name's interval multiplication trick, or San's division method, you can also use the numtodsinterval() function:
ITEM_LAST_UPDATED <= sysdate - numtodsinterval(ITEM_UPDATE_TOLERANCE, 'HOUR')
As an example:
select sysdate, sysdate - numtodsinterval(3, 'HOUR') from dual;
SYSDATE SYSDATE-NUMTODSINTE
------------------- -------------------
2014-03-07 19:08:27 2014-03-07 16:08:27
Well you can try using simple calculation
select ITEM_TYPE from MY_TABLE
where
ITEM_LAST_UPDATED
<=
sysdate - (ITEM_UPDATE_TOLERANCE/24);
Calculation of ITEM_UPDATE_TOLERANCE/24 will convert hours into days and then can be subtracted from sysdate.