Get difference between day just when the difference is positive - sql

Using Postgresql, I need to substract two dates and to show the result just when the result of the difference between dates is positive or 0. In order to substract the dates I am using this:
SELECT
EXTRACT(EPOCH FROM ('2019-02-11 17:59:01.953894'::timestamp - '2019-12-09 02:08:16.01493'::timestamp))/60
However, I would need something like this:
SELECT
DECODE(SIGN(EXTRACT(EPOCH FROM ('2019-02-11 17:59:01.953894'::timestamp - '2019-12-09 02:08:16.01493'::timestamp))/60 as d),-1, None,
,1, d)
Running the previous query, I am getting an error in the following:
ERROR: syntax error at or near "as"
LINE 2: ...mestamp - '2019-12-09 02:08:16.01493'::timestamp))/60 as df)
^
Do you have an idea how to get over this?
Thanks a lot

You could use GREATEST to turn negative values to 0:
GREATEST(
EXTRACT(EPOCH FROM (ts1 - ts2))/60,
0
)
Or, if you want a null result when the difference is negative, you can use a case expression that compares the timestamps before attempting to substract them:
CASE WHEN ts1 > ts2 THEN EXTRACT(EPOCH FROM (ts1 - ts2))/60 END

Try this:
SELECT greatest((EXTRACT(epoch from age('2019-02-11', now())) / 86400)::int, 0)

Related

CAST a calculation from dates into INT

I am learning BigQuery, and to practice I wanted to subtract a date from CURRENT_DATE (to calculate how many days since a last log in), but the result appears as a date.
I tried to CAST and SAFE_CAST but it gives me error.
# Gives calculaiton result as a date
SELECT
short_name,
CURRENT_DATE-last_log_in AS days_wo_log_in,
FROM `noted-wares-328320.demo.test_date`;
# Error invalid cast from INTERVAL to INT64
SELECT
short_name,
CAST (CURRENT_DATE-last_log_in as INT) AS days_wo_log_in,
FROM `noted-wares-328320.demo.test_date`;
Table that appears
Is there a way I am missing?
Thank you,
Use DATE_DIFF:
SELECT DATE_DIFF(CURRENT_DATE(), last_log_in, DAY) AS days_wo_log_in
FROM `noted-wares-328320.demo.test_date`;
Another approach
SELECT
short_name,
EXTRACT(DAY FROM CURRENT_DATE-last_log_in) AS days_wo_log_in
FROM `noted-wares-328320.demo.test_date`
with output

How to remove the decimals when Subtracting casted Dates (EPOCH) in SQL Developer

I am subtracting two epoch dates from each other to get a positive Integer that shows the number of days that has passed from creation to completion (aka modification).
Here is a snippet from my query, that accomplishes that from SQL Developer 20.2.0:
(TO_DATE('19700101', 'YYYYMMDD') + (DATEMODIFIED / 86400))-(TO_DATE('19700101', 'YYYYMMDD') + (DATECREATED / 86400)) AS "Age at Completion",
However, this results in an output of:
74.2922256787899889869
I don't need to see all those decimal places. A result such as this would be sufficient:
74.2922256787899889869 = 74
or
74.5922256787899889869 = 74
I think the ROUND function might be what I am looking for but I have no clue how to actually use it in that line. Can someone please assist? Thank you in advance.
(A + B) - (A + C) == A + B - A - C == B - C
So why not simply ROUND((DATECREATED - DATEMODIFIED) / 86400)?
Or maybe this:
DATEMODIFIED * INTERVAL '1' SECOND - DATECREATED * INTERVAL '1' SECOND
EXTRACT(DAY FROM (DATECREATED - DATEMODIFIED) * INTERVAL '1' SECOND)

round GETDATE (SQL Server)

I have a function which is working fine in MySQL
round((now()-ts/60) as tdiff
(round the result of subtracting the current datetime from ts (also a datetime) divided by 60)
Attempting (and failing) to convert this for SQL Server.
Tried -
round((GETDATE()-ts/60) as tdiff
but that results in round function requires 2 or 3 parameters (which to me it does), so modified to -
round((GETDATE()-ts/60,0) as tdiff
but that results in the datatypes (GETDATE and ts) are incompatible in the subtract operator.
So then I attempted to cast both GETDATE and ts as date and that made no difference.
ts is a conventional datetime i.e.
2918-04-20 11:05:09 and I assumed GETDATE returned the same format.
As an example if GETDATE is today and ts is 2018-04-20 11:05:09 then tdiff is
6850891 (round effectively removes the dashes and colons and concatenates the datetime producing 20180420110509 for 2018-04-20 11:05:09 and 20180831164000 for 2018-08-31 16:40:00 and then divides by 60 to get 6850891.
Is there a remedy for this?
Regards, Ralph
GETDATE(), as per the documentation, returns a datetime. A datetime is accurate to 1/300 of a second, and it's accuracy cannot be changed.
If you want the time accurate to a second, you need to convert to a datetime2(0):
SELECT CONVERT(datetime2(0),GETDATE());
Also, however, don't use syntax like GETDATE()-ts. use the functions DATEADD and DATEDIFF for date maths.
I've no idea what GETDATE()-ts/60 is trying to acheive. Perhaps the number of minutes between the 2? DATEDIFF counts the "ticks" between 2 dates/times, thus DATEDIFF(MINUTE,'00:00:59','00:01:00') would return 1, despite there only being 1 second between the 2 times. This is because the minute value has "ticked" once (from 0 to 1). Therefore you might want to use DATEDIFF(SECOND,'00:00:59','00:01:00') / 60. This would return 0, as 1 / 60 in integer math is 0 (as is 59 / 60).
I think you want to use the DATEDIFF function:
DATEDIFF ( datepart , startdate , enddate )
DATEDIFF ( second, ts, GETDATE())
DATEDIFF ( second, ts, GETDATE())
DATEDIFF ( minute, ts, GETDATE())
DATEDIFF ( hour, ts, GETDATE())
The first argument tells it which increment of time to return.
If you are trying to find the difference between two values, then use datediff(). For instance:
select datediff(day, getdate(), ts)
gets the difference in days.
date_diff() or a related function would also be the right approach in MySQL.
sorry, I don't know if I have understand the question, you need to do date-date/60 and round the result?
In this case you have to change the minus ("-") with the DATEDIFF("Type return example DAYS", GETDATE(), ts).
So you will have ROUND((DATEDIFF(DAY,GETDATE(),ts)/60,0)
Please try and let me know if it will works for you
Bye

SQL Server Date time conversion giving incorrect result?

I have 6 digit value in one column that I need to convert to date-time. I tried two different formula given below.
(DATEADD(day, CONVERT(int, COLUMNNAME)-((1000*(CONVERT(int, COLUMNNAME)/100)))-1, DATEADD(year, CONVERT(int, COLUMNNAME/1000), '1 Jan 1900'))) as Order_date
But this is giving following error message:-
Adding a value to a 'datetime' column caused an overflow. [SQLSTATE=22007, SQLERRORCODE=517]
convert(datetime, (convert (int, COLUMNNAME)), 6) as Order_date
And this is giving incorrect value for date. There is one particular value 118150 that should result into 2018-05-30 :00:00:00, but my statement is returning 2223-06-27 00:00:00
Can anybody please help what is causing error with first statement and how can I modify it to run on entire table.
If I understand the date format correctly, this will work:
select dateadd(day, x % 1000 - 1, datefromparts(1900 + x / 1000, 1, 1))
from (values (118150)) v(x)

query to subtract date from systimestamp in oracle 11g

I want to perform a subtraction operation on the date returned from another query and the system time in oracle SQL. So far I have been able to use the result of another query but when I try to subtract from systimestamp it gives me the following error
ORA-01722: invalid number
'01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
Below is my query
select round(to_number(systimestamp - e.last_time) * 24) as lag
from (
select ATTR_VALUE as last_time
from CONFIG
where ATTR_NAME='last_time'
and PROCESS_TYPE='new'
) e;
I have also tried this
select to_char(sys_extract_utc(systimestamp)-e.last_time,'YYYY-MM-DD HH24:MI:SS') as lag
from (
select ATTR_VALUE as last_time
from CONFIG
where ATTR_NAME='last_time'
and PROCESS_TYPE='new'
) e;
I want the difference between the time intervals to be in hours.
Thank you for any help in advance.
P.S. The datatype of ATTR_VALUE is VARCHAR2(150). A sample result of e.last_time is 2016-09-05 22:43:81796
"its VARCHAR2(150). That means I need to convert that to date"
ATTR_VALUE is a string so yes you need to convert it to the correct type before attempting to compare it with another datatype. Given your sample data the correct type would be timestamp, in which case your subquery should be:
(
select to_timestamp(ATTR_VALUE, 'yyyy-mm-dd hh24:mi:ss.ff5') as last_time
from CONFIG
where ATTR_NAME='last_time'
and PROCESS_TYPE='new'
)
The assumption is that your sample is representative of all the values in your CONFIG table for the given keys. If you have values in different formats your query will break on some other way: that's the danger of using this approach.
So finally after lots of trial and errors I got this one
1. Turns out initially the error was because the data_type of e.last_time was VARCHAR(150).
To find out the datatype of a given column in the table I used
desc <table_name>
which in my case was desc CONFIG
2. To convert VARCHAR to system time I have two options to_timestamp and to_date. If I use to_timestamp like
select round((systimestamp - to_timestamp(e.last_time,'YYYY-MM-DD HH24:MI:SSSSS')) * 24, 2) as lag
from (
select ATTR_VALUE as last_time
from CONFIG
where ATTR_NAME='last_time'
and PROCESS_TYPE='new'
) e;
I get an error that round expects NUMBER and got INTERVAL DAY TO SECONDS since the difference in date comes out to be like +41 13:55:20.663990. To convert that into hour would require a complex logic.
An alternative is to use to_data which I preferred and used it as
select round((sysdate - to_date(e.last_time,'YYYY-MM-DD HH24:MI:SSSSS')) * 24, 2) as lag
from (
select ATTR_VALUE as last_time
from CONFIG
where ATTR_NAME='last_time'
and PROCESS_TYPE='new'
) e;
This returns me the desired result i.e. the difference in hours rounded off to 2 floating digits