How to find the names of transactions that have been active for more than 30 minutes from the current time using the START_TIME column of V$TRANSACTION table in Oracle?
We can do arithmetic with dates in Oracle. Sysdate is the current datetime. There are 48 half-hours in a day. So:
select *
from V$TRANSACTION
where to_date(start_time, 'mm/dd/yyyy hh24:mi:ss') <= sysdate - (1/48)
Hmmm, it seems slightly odd that V$TRANSACTION.start_time uses a different format mask from sysdate. Anyway, you can avoid the ORA-01843 error with an explicit date conversion.
Related
sql table
here in the table above named carpooling contains a column name start_on which has date time as timestamp i have to write a query to select all the rows having date as 25-11-20 using to_char and to_date.
You write a timestamp literal like this:
timestamp '2020-11-25 00:00:00'
so the full filtering condition will be
where start_on >= timestamp '2020-11-25 00:00:00'
and start_on < timestamp '2020-11-26 00:00:00'
Note that dates and timestamps are different in Oracle, and dates include times down to the second (this is for historical reasons - originally there was only the date type, and timestamp was added much later).
Use the TRUNC function, along with date and interval literals:
SELECT *
FROM CARPOOLING
WHERE START_ON BETWEEN DATE '2020-11-25'
AND (DATE '2020-11-26' - INTERVAL '0.000001' SECOND)
You can simply use to_date, but it's recommended to remove the time when comparing the dates. Otherwise, rows having the same date, but a different time will not be selected. Removing the time can be done using TRUNC.
So you can do something like this:
SELECT * FROM carpooling
WHERE TRUNC(start_on) = TO_DATE('2020-11-25','yyyy.mm.dd');
If you don't want to check the 25th of November 2020, but another data, change the date to match your goal.
I'm having trouble with filtering a date and time for anything two hours before and sooner. I tried this:
SELECT *
FROM
table
where
date >= sysdate - 1
AND
TO_DATE( Time, 'HH24:MI:SS' ) >= TO_DATE( sysdate, 'HH24:MI:SS' ) - 2
But I'm getting an inconsistent type error which is what I thought I was handling with the TO_DATE() function but I guess not.
sysdate is already a date (and time), so TO_DATE( sysdate, 'HH24:MI:SS' ) doesn't make any sense.
You didn't provide your data types for your date and time columns in table, so I'm going to assume they're both varchar2(10) with formats MM/DD/YYYY and HH24:MI:SS respectively.
I'm also going to go ahead and change your example table and column names, since they're invalid names to use in a real query.
-- example data
with my_table as (select '06/13/2019' as date_column, '09:40:34' as time_column from dual)
-- your query
SELECT *
FROM
my_table
where
to_date(date_column || ' ' || time_column, 'MM/DD/YYYY HH24:MI:SS') >= sysdate - 2/24
What I'm doing here is to combine your date and time strings into one date-time string, then converting it to an Oracle date type (actually date+time). Then we compare it to sysdate - 2/24, which says to take the current time and subtract 2/24ths of a day, which is 2 hours.
For this example, you might need to change the example data date_column and time_column values to something from the past 2 hours, depending on when you run this and what time zone you're in.
Usecase: Query to select the records for a whole day and it should run regularly.
This is my query.
Select to_char(in_date + interval '12' hour, 'DD-MON-YYYY HH24:MI:SS')
from my_table
where incoming_date > sysdate-2 and incoming_date < sysdate
I need to select yesterday's data only. Because of the conversion in the select statement I got today's data also. How do I select only yesterday's data? My DB is in UTC+7.00 standard. I need to display it in local standard so that I did a conversion in select statement. And how do I display only yesterday's data?
I'm stuck. Please help me
To get all data from yesterday you should use
SELECT TO_CHAR(IN_DATE + INTERVAL '12' HOUR, 'DD-MON-YYYY HH24:MI:SS')
FROM MY_TABLE
WHERE INCOMING_DATE BETWEEN TRUNC(SYSDATE) - INTERVAL '1' DAY
AND TRUNC(SYSDATE) - INTERVAL '1' SECOND
If, for example, SYSDATE is 05-NOV-2017 18:56:35, the time interval used in the BETWEEN comparison will be from 04-NOV-2017 00:00:00 to 04-NOV-2017 23:59:59. BETWEEN comparisons are inclusive of both endpoints so this will only return data with an INCOMING_DATE of sometime on 04-NOV-2017, in this example.
Best of luck.
only to get the
yesterday's data
make your
WHERE condition as
incoming_date between trunc(sysdate) - interval '1' day and trunc(sysdate) - interval '1' second
My DB is in UTC+7.00 standard. I need to display it in local standard so that I did a conversion in select statement.
Using a magic value (INTERVAL '12' HOUR) does not describe what it means or the assumptions you made when chosing that value. Instead you can better describe the process by using FROM_TS( timestampvalue, timezonestring ) to convert the value from a TIMESTAMP to a TIMESTAMP WITH TIME ZONE data type and then use AT LOCAL TIME to convert it to the local time. Then if you have daylight savings time or port the query to another international location then it will still display in the current local time. Like this:
SELECT TO_CHAR(
FROM_TZ( CAST( in_date AS TIMESTAMP ), '+07:00' ) AT LOCAL TIME,
'DD-MON-YYYY HH24:MI:SS'
)
FROM my_table
WHERE incoming_date >= TRUNC( SYSDATE ) - INTERVAL '1' DAY
AND incoming_date < TRUNC( SYSDATE )
And how do I display only yesterday's data?
TRUNC( SYSDATE ) will truncate today's date back to midnight. To get yesterday's data then you can get values that are greater or equal to TRUNC( SYSDATE ) - INTERVAL '1' DAY (one day before midnight today) and also less than TRUNC( SYSDATE ) (midnight today).
I'm not exactly sure I get your question, but I think I can explain some stuff.
I'll be assuming your table is a bit like this:
date_added | some_data | some_more_data
------------|-----------|----------------
date | data1 | data2
As I understand your goal is to fetch all the rows that were added to a table the day before the query is run using a select statement. but your current attempt fails at doing so by also returning today's results.
Here is what's happening (I think):
SYSDATE doesn't just give you the current date, it also gives you the time. You can see that for your self by simply altering your current session and setting the date/time format to one that includes both time and date
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';
The reason why you would be getting today's rows is simple, your query is asking for all the rows who's date_added field is between right now and right now - 24 hours. Not today and today - 24 hours.
So what is the solution?
Use the TRUNC function to trim the SYSDATE to the day instead!
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions201.htm
SELECT
T.*
FROM
MY_TABLE T
WHERE
T.DATE_ADDED BETWEEN (TRUNC(SYSDATE,'day') - 1) AND TRUNC(SYSDATE,'day');
As you did mention timezones being a thing keep in mind that SYSDATE returns the date on the server itself and not your computer's.
More on that here: https://stackoverflow.com/a/17925834/7655979
Usually I compare the date only using Trunc.
WHERE trunc(incoming_date) = trunc(sysdate-1)
I found a bizarre snippet which is confusing me so I thought I'll ask the experts.
Let assume a tableA got following columns with data:
"START_TIME":1399075198
"END_TIME":1399075200
"START_DATE":"02-MAY-14"
"END_DATE":"03-MAY-14"
Now query 1:
SELECT MIN(start_date) INTO sdate FROM tableA;
query 2:
SELECT TRUNC(sdate, 'HH24') + INTERVAL '30' MINUTE from dual;
So if start-date = '02-MAY-14', how would that truncate to 'HH24'?
The expression:
TRUNC(sdate, 'HH24')
cuts off everything from a date that is smaller than an hour, i.e. the minutes and seconds. For the specific date:
TRUNC('02-MAY-14','HH24')
it returns the date unchanged. It only makes sense if the Oracle date contains a time component.
Possibly, your SQL tool (SQL Developer, TOAD etc.) is configured to not display the time part of Oracle dates. So the original date might in fact be 02-MAY-14 09:03:25. Then it would return:
02-MAY-14 09:00:00
You mention the columns START_TIME and END_TIME but don't use them in the SQL queries. What are they for?
As start_date does not have a time part in your example, TRUNC is superfluous here. If however it had a timepart, if for example start_time had been added to start_date before, then TRUNC would remove minutes, seconds and microseconds, only keeping the date and hour because of 'HH24' which means "truncate datetime down to full hour".
In Oracle the date datatype inherently store the time as well.
Try executing the below query. It should clear things up a bit:
SELECT TO_CHAR(SYSDATE,'DD-MON-YYYY HH:MI:SS'), TO_CHAR(TRUNC(SYSDATE,'HH24'),'DD-MON-YYYY HH:MI:SS') FROM DUAL;
Heyho,
I need to grab some datas from actions which been done from date A 00:00:00 and date B 00:00:00 (in this case
Date A: 16.07.2010
Date B: 20.07.2010)
so i wrote this select-statement:
Select avg(cnt),fext from (
Select
to_char(mytable.dateadded, 'DD.MM.YYYY') dateadded,
fext,
count(id) cnt
from mytable
where dateadded between
to_date('16.07.2010', 'dd,MM,YYYY') and
to_date('20.07.2010', 'dd,MM,YYYY')
group by
to_char(mytable.dateadded, 'DD.MM.YYYY'),
fext)
group by fext;
The original (and working) statement had:
to_date('16.07.2010 00:00:00', 'dd,MM,YYYY HH24:Mi:SS') and
to_date('20.07.2010 00:00:00', 'dd,MM,YYYY HH24:Mi:SS')
so the question is: does the
to_date('16.07.2010', 'dd,MM,YYYY') and
to_date('20.07.2010', 'dd,MM,YYYY')
already set the time to date A and B to 00:00:00?
Greetz
If you does not specify time part of date it will be 00:00:00.
If you worry about time part you always can truncate time part:
Trunc(to_date('16.07.2010', 'dd.MM.YYYY')) and
Trunc(to_date('20.07.2010', 'dd.MM.YYYY'))
The easiest way is to use ANSI date literals, which doesn't allow time to be specified and is thus with a 00:00:00 time part internally:
dateadded between date '2010-07-16' and date '2010-07-20'
Your expressions look odd, as your date string has dots as the time component separator, but your date format has commas. Oracle accepts it though:
rwijk#XE> select to_date('16.07.2010', 'dd,MM,YYYY') from dual;
TO_DATE('16.07.2010
-------------------
16-07-2010 00:00:00
1 row selected.
I'd use the ANSI date literal for its simplicity.
Regards,
Rob.
this query will returns you one row which answers your question i think :
SELECT TO_DATE('16.07.2010 00:00:00', 'dd,MM,YYYY HH24:Mi:SS'),
TO_DATE('16.07.2010', 'dd,MM,YYYY')
FROM dual
WHERE to_date('16.07.2010 00:00:00', 'dd,MM,YYYY HH24:Mi:SS') = to_date('16.07.2010', 'dd,MM,YYYY')
This is one thing that SQL is consistent about - if you don't provide a time portion on a DATE data type that includes a time portion (IE Oracle, PostgreSQL while MySQL and SQL Server explicitly call it DATETIME), then the time portion is defaulting to exactly midnight of that date - 00:00:00. And being midnight, that means the start of the date - if you want to include the entire date in a date comparison, the value's time portion needs to be 23:49:49 -- a second to midnight.
23:59:59 is a second to midnight. Essentially midnight is defined as the start of a day: 00:00:00. Then the seconds clock up to the end of the day.