I would like to extract data where all the records were created after 19:00:00 yesterday until now. What I have so far is :
Select * from table where lstupdt >=trunc(sysdate -1);
How to specify after 19:00:00 hours?
Hmmm . . . How about this?
where lstupdt >= trunc(sysdate - 1) + 19 / 24
Or, alternatively, to be more accurate:
where lstupdt >= trunc(sysdate - 1, 'day') + interval '19' hour
or:
where lstupdt >= trunc(sysdate, 'day') - interval '5' hour
Related
I have table which has two columns like: start_date and end_date.
sample value of start_time/end_time= 9/24/2019 12:22:43 AM.
now i need to write a query which will throw the data where time_interval(end_date-start_date) is more than 6 hours.
Use an INTERVAL literal:
WHERE end_date > start_date + INTERVAL '6' HOUR
Use NUMTODSINTERVAL function:
WHERE end_date > start_date + NUMTODSINTERVAL( 6, 'HOUR' );
Or use fractions of a day:
WHERE end_date > start_date + 6 / 24;
You can just use:
WHERE end_date-start_date > 0.25 --(which is 1 / 24 * 6)
How do I get the last day of the month to be 11:59:59 pm? Right now it is showing 05/31/2019 12:00 AM. If I just do sysdate it just shows the time I ran it. Thanks.
LAST_DAY(TRUNC(SYSDATE,'MM'))
Try adding one day to the last day of the current month, then subtracting one minute:
SELECT
LAST_DAY(TRUNC(SYSDATE,'MM')) + INTERVAL '1' DAY - INTERVAL '1' SECOND
FROM dual;
Or, if you want to also see the time component, use CURRENT_TIMESTAMP in place of SYSDATE:
SELECT
LAST_DAY(TRUNC(CURRENT_TIMESTAMP,'MM')) + INTERVAL '1' DAY - INTERVAL '1' SECOND
FROM dual;
This outputted:
30.06.2019 23:59:59
The oldfashioned way would be to subtract a second (that's what 1 / (24*60*60) represents as there are 24 hours in a day, 60 minutes in an hour and 60 seconds in a minute) from the first day of the next month (and that's what trunc(add_months(sysdate, 1)) does):
SQL> select sysdate today,
2 trunc(add_months(sysdate, 1)) - 1/(24*60*60) result
3 from dual;
TODAY RESULT
---------------------- ----------------------
06/01/2019 07:52:40 AM 06/30/2019 11:59:59 PM
SQL>
I would use:
SELECT TRUNC(SYSDATE, 'MM') + INTERVAL '1' MONTH - INTERVAL '1' SECOND
FROM dual;
(This has one less step than Tim's solution.)
Or in the older-fashioned method:
SELECT ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1) - 1/(24*60*60)
If you convert this to a timestamp, you will see the time value:
SELECT CAST(TRUNC(sysdate, 'MM') + INTERVAL '1' MONTH - INTERVAL '1' SECOND as TIMESTAMP)
FROM dual;
I'm using a SQL statement in Power BI on a Oracle based system to pull some data when the day of the week equals Monday. Ideally, I'm trying to make it so it works in any location. I'm trying to convert "C_endtime" to a day of the week and compare it to the sysdate. Basically if its Monday then I want all the data from that table back to Friday, every other day would just be the previous day's data.
In other words what I'm ultimately shooting for is:
...
where
if
sysdate = 1 (Monday)
then
pull data back 3 days (sysdate -3)
else
one day (sysdate -1)
Here is my attempt:
SELECT
Example Fields
FROM
Example Table
WHERE
TO_CHAR(c_endtime, 'D', 'NLS_DATE_LANGUAGE=ENGLISH') >
CASE TO_CHAR(sysdate, 'D', 'NLS_DATE_LANGUAGE=ENGLISH')
WHEN '1' then sysdate - 3
ELSE
sysdate - 1
END
AND
c_workcentrename = ####
I get the error: "ORA-01840: input value not long enough for date format."
The result of TO_CHAR(c_endtime, 'D') depends on the current user session NLS-Setting, i.e. result is not predictable.
Better use condition like this:
IF TO_CHAR(c_endtime, 'fmDay', 'NLS_DATE_LANGUAGE = American') = 'Monday' THEN
or
TRUNC(c_endtime) = TRUNC(c_endtime, 'IW') THEN
Assuming that on Monday you want everything since the beginning of Friday and on other days since the beginning of the previous day, then you can use logic like this:
select . . .
from . . .
where ( (trunc(sysdate) = trunc(sysdate, 'IW') and c_endtime >= trunc(sysdate - 3)) or
(trunc(sysdate <> trunc(sysdate, 'IW') and c_endtime > trunc(sysdate - 1))
) and
c_workcentrename = ###;
ISO weeks start on Monday and that is not changing anytime soon or in any environment.
You can simplify the above to:
where ( (trunc(sysdate) = trunc(sysdate, 'IW') and c_endtime >= trunc(sysdate - 3)) or
(c_endtime >= trunc(sysdate - 1))
) and
c_workcentrename = ###;
I have come across a query which has me curious whether the programmer was show boating or whether there is merit to the way it has been done in terms of performance. I have no clue as to why the from time is 01:59 rather than 00:00, this would actually remove some of the results that would actually want to be included.
This is the where clause of the query
WHERE REPORTDATE BETWEEN TRUNC(SYSDATE - 21) + 01 / 24 + 59 / (24 * 60) + 59 / (24 * 60 * 60)
AND TRUNC(SYSDATE) + 23 / 24 + 59 / (24 * 60) + 59 / (24 * 60 * 60)
and if my math is correct, is the same as
WHERE REPORTDATE BETWEEN to_date('13/04/2017 01:59','dd/mm/yyyy hh24:mi')
AND to_date('04/05/2017 23:59','dd/mm/yyyy hh24:mi')
Is there any benefit in the first calculated where clause over the second?
You can use interval literals to get rid of all the arithmetic and simplify the query:
WHERE REPORTDATE BETWEEN TRUNC( SYSDATE ) - INTERVAL '20 22:00:01' DAY TO SECOND
AND TRUNC( SYSDATE ) + INTERVAL '00 23:59:59' DAY TO SECOND
or
WHERE REPORTDATE BETWEEN TRUNC( SYSDATE ) - INTERVAL '21' DAY
+ INTERVAL '01:59:59' HOUR TO SECOND
AND TRUNC( SYSDATE ) + INTERVAL '00 23:59:59' DAY TO SECOND
or
WHERE REPORTDATE >= TRUNC( SYSDATE ) - INTERVAL '20 22:00:01' DAY TO SECOND
AND REPORTDATE < TRUNC( SYSDATE ) + INTERVAL '1' DAY
It is hard to imagine a performance difference, based on different ways of calculating constants in a query.
I would write this using something like this:
WHERE REPORTDATE >= CAST(TIMESTAMP '2017-04-13 02:00:00' as DATE) and
REPORTDATE < DATE '2017-05-05'
If you are going to include date/time constants, use the built-in mechanisms that support standard formats.
or for more flexibility based on the current date:
WHERE REPORTDATE >= TRUNC(sysdate) - 21 + 2 / 24 AND
REPORTDATE < TRUNC(sysdate) + 1
(or, if 1:59 is really intended . . . then TRUNC(sysdate) - 21 + (1 * 60 + 59) / (24 * 60).)
I am just trying to add 1 hour to a value, it is kind of complicated on where and why i am doing this but basically i just need to query something like this
select DATE_ADD(hh,1,'2014-10-15 03:30:00 pm') from dual
I keep reading old articles that say to use dateAdd or date_add but I keep getting invalid identifier errors.
select sysdate + 1/24 from dual;
sysdate is a function without arguments which returns DATE type
+ 1/24 adds 1 hour to a date
select to_char(to_date('2014-10-15 03:30:00 pm', 'YYYY-MM-DD HH:MI:SS pm') + 1/24, 'YYYY-MM-DD HH:MI:SS pm') from dual;
Use an interval:
select some_date_column + interval '1' hour
from your_table;
You can use INTERVAL type or just add calculated number value - "1" is equal "1 day".
first way:
select date_column + INTERVAL '0 01:00:00' DAY TO SECOND from dual;
second way:
select date_column + 1/24 from dual;
First way is more convenient when you need to add a complicated value - for example, "1 day 3 hours 25 minutes 49 seconds".
See also: http://www.oracle-base.com/articles/misc/oracle-dates-timestamps-and-intervals.php
Also you have to remember that oracle have two interval types - DAY TO SECOND and YEAR TO MONTH.
As for me, one interval type would be better, but I hope people in oracle knows, what they do ;)
Old way:
SELECT DATE_COLUMN + 1 is adding a day
SELECT DATE_COLUMN + N /24 to add hour(s) - N being number of hours
SELECT DATE_COLUMN + N /1440 to add minute(s) - N being number of minutes
SELECT DATE_COLUMN + N /86400 to add second(s) - N being number of seconds
Using INTERVAL:
SELECT DATE_COLUMN + INTERVAL 'N' HOUR or MINUTE or SECOND - N being a number of hours or minutes or seconds.
To add/subtract from a DATE, you have 2 options :
Method #1 :
The easiest way is to use + and - to add/subtract days, hours, minutes, seconds, etc.. from a DATE, and ADD_MONTHS() function to add/subtract months and years from a DATE. Why ? That's because from days, you can get hours and any smaller unit (1 hour = 1/24 days), (1 minute = 1/1440 days), etc... But you cannot get months and years, as that depends on the month and year themselves, hence ADD_MONTHS() and no add_years(), because from months, you can get years (1 year = 12 months).
Let's try them :
SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints current date: 19-OCT-2019 20:42:02
SELECT TO_CHAR((SYSDATE + 1/24), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour: 19-OCT-2019 21:42:02
SELECT TO_CHAR((SYSDATE + 1/1440), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 minute: 19-OCT-2019 20:43:02
SELECT TO_CHAR((SYSDATE + 1/86400), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 second: 19-OCT-2019 20:42:03
-- Same goes for subtraction.
SELECT SYSDATE FROM dual; -- prints current date: 19-OCT-19
SELECT ADD_MONTHS(SYSDATE, 1) FROM dual; -- prints date + 1 month: 19-NOV-19
SELECT ADD_MONTHS(SYSDATE, 12) FROM dual; -- prints date + 1 year: 19-OCT-20
SELECT ADD_MONTHS(SYSDATE, -3) FROM dual; -- prints date - 3 months: 19-JUL-19
Method #2 : Using INTERVALs, you can or subtract an interval (duration) from a date easily. More than that, you can combine to add or subtract multiple units at once (e.g 5 hours and 6 minutes, etc..)
Examples :
SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints current date: 19-OCT-2019 21:34:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' HOUR), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour: 19-OCT-2019 22:34:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' MINUTE), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 minute: 19-OCT-2019 21:35:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' SECOND), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 second: 19-OCT-2019 21:34:16
SELECT TO_CHAR((SYSDATE + INTERVAL '01:05:00' HOUR TO SECOND), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour and 5 minutes: 19-OCT-2019 22:39:15
SELECT TO_CHAR((SYSDATE + INTERVAL '3 01' DAY TO HOUR), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 3 days and 1 hour: 22-OCT-2019 22:34:15
SELECT TO_CHAR((SYSDATE - INTERVAL '10-3' YEAR TO MONTH), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date - 10 years and 3 months: 19-JUL-2009 21:34:15
The calculation is simple
if you want to add 1 hour in the date .
every day have 24 hour , you can add .
select sysdate + 1/24 from dual;
if you want 1 day to add
select sysdate + 24/24 from dual;
or
select sysdate + 1 from dual;
same as for 2, 3 , 4 day
For static date you have the answer below.