SQL : How sysdate minus a value works? - sql

I found below code in my existing project.
select * from mytable where SomeColumn_date >= trunc(sysdate)-.25/24;
Sample value for SomeColumn_date is 22-JUN-17 05:46:55
How does SomeColumn_date >= trunc(sysdate)-.25/24 work on Date data type?

Different database engines allow different operations to be applied to date data types. For the most part, an operation of <Date Value> +/- 1 will add or subtract one day to that date value. This is syntactically equivalent to the dateadd function when using days.
In your example here, the -.25/24 resolves to the number equivalent of -15 minutes, which is then subtracted from your date value.
It is essentially a much less readable version of datedd(min,-15,<Date Value>).

From the documentation of TRUNC (I'm guessing you are using Oracle):
The TRUNC (date) function returns date with the time portion of the day truncated to the unit specified by the format model fmt. [...] If you omit fmt, then date is truncated to the nearest day.
The result of trunc(sysdate) would be the present date without the time component. Now .25/24 (actually meaning 0.25/24) is substracted from that. If you substract a date using - the operand is always in days. 0.25/24 would be a form to express a quarter of an hour.
So trunc(sysdate)-.25/24 would result in yesterday 23:45.

Ok so 2 things are happening here:
trunk(date,fmt)
The TRUNC (date) function returns date with the time portion of the day truncated to the unit specified by the format model fmt. If you omit fmt, then date is truncated to the nearest day.
So if you have suppose 22-JUN-17 05:46:55 you get 22-JUN-17. Since you don't have the fmt
DATETIME - .25/24 implies .25 hours before your current Date time.
But since you have only DATE all it does is .25 hours before todays 12:00 AM i.e yesterdays 11:45PM
SomeColumn_date >= trunc(sysdate)-.25/24
So suppose if its 22-JUN-2017 right now the date is compared to 21-JUN-2017 11:45 PM
NOTE: - is for before current time, + is for after the current time

Related

The accuracy of oracle when compare two date in SQL

It is in two procedures which are running in order. In procedure one, the running timestamp of system time is 2019/5/30 12:02:58.100. The sql is as below
insert into A(xxx,xxx,cdate) values(xxx,xxx,sysdate)
And I find the cdate field of this inserted row is 2019/5/30 12:02:58, without the millisecond.
And then procedure two runs, the running timestamp of system time is 2019/5/30 12:02:58.200. The SQL is as below
select xxx from A where cdate<sysdate
This returns none result. It is weird because I just inserted a row with cdate 2019/5/30 12:02:58. This should be less than sysdate.
When Oracle stores date value like 2019/5/30 12:02:58, does it throw millsecond away or does it just store it in background and not show it?
While comparing cdate<sysdate, which two values does it use? I guess it is using 2019/5/30 12:02:58 < 2019/5/30 12:02:58, so this returns false.
When Oracle stores date value like 2019/5/30 12:02:58, does it throw millsecond away or does it just store it in background and not show it?
A date value does not have any millisecond component to throw away. sysdate returns a DATE data type:
This data type contains the datetime fields YEAR, MONTH, DAY, HOUR, MINUTE, and SECOND. It does not have fractional seconds or a time zone.
In your procedures you are looking at a TIMESTAMP value:
This data type contains the datetime fields YEAR, MONTH, DAY, HOUR, MINUTE, and SECOND. It contains fractional seconds but does not have a time zone.
... or a variant that does have a time zone, like TIMESTAMP WITH TIME ZONE, as returned by systimestamp:
This data type contains the datetime fields YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, TIMEZONE_HOUR, and TIMEZONE_MINUTE. It has fractional seconds and an explicit time zone.
While comparing cdate<sysdate, which two values does it use? I guess it is using 2019/5/30 12:02:58 < 2019/5/30 12:02:58, so this returns false.
As your insert statement is using sysdate, it doesn't really matter at this point whether cdate is defined as DATE or TIMESTAMP, if the latter then the fraction seconds part is just truncated to zero. And sysdate also returns a DATE, so yes, it is either doing:
2019-05-30 12:02:58 < 2019-05-30 12:02:58
or
2019-05-30 12:02:58.000 < 2019-05-30 12:02:58
which may involve an implicit cast. Either way the result is indeed false.
If you want to compare values that might be within the same second then you have to use a TIMESTAMP. Define your column as one of the TIMESTAMP variants as appropriate, and then use systimestamp instead of sysdate both for your insert and for the comparison. It all has to be timestamps - if any part of what you do stays as a date then at some point the fractional seconds will be lost and you'll be in the same position you are now.
If your column is a DATE type then it doesn't store milliseconds. SYSDATE doesn't return them either. Ensure your column is a TIMESTAMP with a suitable number for fractional precision to store the milliseconds you want, and ensure you're comparing it with SYSTIMESTAMP

presto - getting days interval (not date)

How do I get the days interval for prestodb? I can convert to milliseconds and convert these to number of days but I am looking if there is any shorter way to do this.
Example: I want to see how many days has it been since the first row inserted in a table.
SELECT
to_milliseconds(date(current_date) - min(created)) / (1000*60*60*24) as days_since_first_row
FROM
some_table
What I am hoping to see: (Either 1 of below)
SELECT
to_days(date(current_date) - min(created)) / (1000*60*60*24) as days_since_first_row
,cast(date(current_date) - min(created)) as days) as days_since_first_row2
FROM
some_table
Unfortunately, daylight savings breaks the solution from the accepted answer. DAY(DATE '2020-09-6' - DATE '2020-03-09') and DAY(DATE '2020-09-6' - DATE '2020-03-08') are both equal to 181 due to daylight savings time and DAY acting as a floor function on timestamps.
Instead, use DATE_DIFF:
DATE_DIFF('day', DATE '2020-09-6', DATE '2020-03-09')
Use subtraction to obtain an interval and then use day on the interval to get number of days elapsed.
presto:default> select day(current_date - date '2018-07-01');
_col0
-------
86
The documentation for this is at https://trino.io/docs/current/functions/datetime.html

Datediff function in Access Database

I am trying to use Datediff function while subtracting two dates. One date is with Date and time stamp and the other with date only. How to get the difference of dates?
Here Column1 is 7/11/2017 4:24:38 PM and Column2 is 15/12/2017 where there is no timestamp.
DateDiff("d",[Column1],[Column2])
Convert the date column into datetime using Format function. See example below.
EDIT: since you want the difference in days and decimal point, I get the difference in hours then divide by 24. You can be as accurate if you want by getting the difference in minutes or seconds but using a different divisor.
SELECT DateDiff("h",
Now(),
Format('04/05/2018','mm/dd/yyyy hh:nn:ss'))/24 AS Expr1;
result: 1.125 days

Conversion date in the format timestamp

I have a date as a timestamp . I have to replace it every day on the date of beginning of 7:00:00 hours a day from the date of timestamp for example . 11-07-2016 7:00:00
For example, I have a date after changing 837072216 837241200 it will need a scalar function .
Your question is very unclear. In fact, there is no actual question...
Never-the-less, you appear to be asking about a conversion from timestamp to a date or time. This is not possible; despite its name, timestamp does not represent a date(time). It is used for versioning of rows, and it's deprecated and replaced by rowversion. Source.

Sysdate Oracle to Run Based on Day

This is probably an easy question for most of you but how can I get this mask to run based on just the day?
If anyone knows Crystal Reports syntax, we have this and it works {PO_RECEIPTS.DATE_RECEIVED} = currentdate
However, when converting to Oracle SQL, how can I the standard: TO_CHAR
(SYSDATE, 'MM-DD-YYYY HH24:MI:SS') to become range so we can selected everything during the day, not just what matched the second in which the report was ran which it never will.
So something like Today from 00:00:00 to 23:59:59 ?
Thank you!
If PO_RECEIPTS.DATE_RECEIVED is a date column where all the times are set to midnight then you can do:
WHERE PO_RECEIPTS.DATE_RECEIVED = TRUNC(sysdate)
If the values have other times then you can use a range:
WHERE PO_RECEIPTS.DATE_RECEIVED >= TRUNC(sysdate)
AND PO_RECEIPTS.DATE_RECEIVED < TRUNC(sysdate) + 1
Truncating a date sets the time to midnight, by default, so TRUNC(sysdate) is midnight this morning. For the range you get all records equal to or later than midnight this morning, and less than midnight tomorrow - which is what TRUNC(sysdate) + 1 gives you, using normal Oracle datetime arithmetic.
You don't really want to convert it to a string with TO_CHAR(); you'd either have to convert all the column values to strings too (which is inefficient and prevents an index being used), or let the string be (implicitly) converted back to a date anyway. It's better to compare a column value with the same data type to reduce or avoid confusion.