Date difference in days in postgresql - sql

I am trying to calculate the difference between dates in days.
Datatype is Text for columns snapshot_date and date_opened.I am getting an ERROR: function date_part(unknown, integer) does not exist
SELECT DATE_PART('day', snapshot_date::date -date_opened::date)::number from my_table

As documented in the manual subtracting one date from the other returns an integer representing the number of days, so:
snapshot_date::date - date_opened::date
is all you need.
This assumes that both columns can safely be cast to a date.

Related

How would SQL treat this date format?

I had a coworker run a data pull for me. The query was essentially
SELECT a, b, c
FROM table
WHERE date >= 06/01/2018
The where clause being June 1, 2018. The query ran but the date filter was incorrect (not ‘2018-06-01’) How did the server interpret the date used? Was any filtering applied?
If you specified exactly as you have shown it, without quotes, then it would probably have:
1) Calculated 6 divided by 1 divided by 2018 (resulting in an integer zero)
2) Converted the dates in your database to an int to match the compare data type, and done a compare.
I expect this returned all your rows.
You can use this (datediff) function.
SELECT a, b, c
FROM table
WHERE datediff(dateVar, from_unixtime(unix_timestamp('2018/06/01','yyyy/MM/dd'),'yyyy-MM-dd')) >= 0
from_unixtime(,'yyyy-MM-dd') converts string to a string of given format, e.g. '2018-06-01'
Alternatively, these are functions which can help:
date_sub(,xxx) subtracts xxx days from the string, and returns a new
string in the same format.
unix_timestamp(string date,string pattern) converts a
string of a given pattern to unix time stamp, ) if fail.
Reference: How to change date format in hive?
This condition is:
WHERE date >= 06/01/2018
The last part is a numerical expression which I believe is interpreted as (06 / 01) / 2018. Depending on the database, this would either be 0 or about 0.00297, depending on whether your database does integer division.
Now the database has a bit of a conundrum. It has a date on one side and a number on the other. The rules of type conversion say to convert the date to a number. Depending on the database, this could be an error or a valid number -- which would be larger than 0.
The correct way to express this is:
WHERE date >= '2018-06-01'
or:
WHERE date >= DATE '2018-06-01'

How to use datediff equivalent in Oracle with YYYYMMDD formatted number?

I have Oracle database columns with the number format YYYYMMDD. I have not been successful in using this format with datediff to get the difference between two dates. The documentation I've read online uses a different format:
DATEDIFF(day,'2008-06-05','2008-08-05')
What's the best way for me to get number of days between two dates given the format available to me in Oracle? Answers not involving datediff are acceptable as long as it gets the number of days between two dates with the format YYYYMMDD.
Simple subtraction in Oracle:
SELECT TO_DATE('20080805','YYYYMMDD') - TO_DATE('20080605','YYYYMMDD')
FROM DUAL;
Oracle doesn't have a DATEDIFF() function. Instead, you can use simple arithmetic with Oracle dates, where subtracting one date from another gives the number of days, and where you can add an subtract days from a given date. (You can also subtract fractions of days, but that might be outside the scope of this answer.)
To convert your NUMBER dates of the format YYYYMMDD to actual dates, just use the TO_DATE() function (I am pretty sure that Oracle will implicitly convert the NUMBER value to a VARCHAR2 before converting to a date; if not, use TO_CHAR() to do that explicitly).
TO_DATE(20150301, 'YYYYMMDD')
To get the difference between two dates, you can do the following:
SELECT TO_DATE(my_number_date1, 'YYYYMMDD') - TO_DATE(my_number_date2, 'YYYYMMDD')
FROM my_table;
Incidentally, if you want to get intervals instead of days, convert to timestamp (using TO_TIMESTAMP()) instead of converting to date.

How to take differece between 2 dates of different format in SQL

I have a table with a LOAD_STRT_DTM colum. This is a date column and values are like this - 18-JUL-14 08.20.34.000000000 AM.
I want to find the data which came before 5 days.
My logic is -
Select * from Table where 24 *(To_DATE(Sysdate,'DD-MM-YY') - To_DATE(LOAD_STRT_DTM,'DD-MM-YY')) >120
The issue is -
Select (To_DATE(Sysdate,'DD-MM-YY') - To_DATE(LOAD_STRT_DTM,'DD-MM-YY')) from table
This query should give the NumberOfDays between two dates. But this is not working, I Doubt, the issue is because of the format of the LOAD_STRT_DTM colum.
Please let me know where i am doint it wrong.
If your column is DATE datatype everything is ok, just shoot an:
select * from table where LOAD_STRT_DTM > sysdate - 5;
No need to convert dates to DATE datatype.
(To_DATE(Sysdate,'DD-MM-YY') - To_DATE(LOAD_STRT_DTM,'DD-MM-YY'))
You don't have to convert a DATE into a DATE again. IT is already a DATE. You just need to use it for date calculations. You use TO_DATE to convert a STRING into a DATE.
For example, if you have a string value like '18-JUL-14', then you would need to convert it into date using TO_DATE. Since your column is DATE data type, you just need to use as it is.
This is a date column
I want to find the data which came before 5 days.
Simply use the filter predicate as:
WHERE load_strt_dtm > SYSDATE - 5;
NOTE : SYSDATE has both date and time elements, so it will filter based on the time too. If you want to use only the date part in the filter criteria, then you could use TRUNC. IT would truncate the time element.
I have answered a similar question, have a look at this https://stackoverflow.com/a/29005418/3989608
It looks like LOAD_STRT_DTM is a TIMESTAMP rather than a DATE, given the number of decimal points following the seconds. The only thing you have to be cautious about is that Oracle will convert a DATE to a TIMESTAMP implicitly where one of the operands is a TIMESTAMP. So the solution
WHERE load_strt_dtm > SYSDATE - 5
will work; as will
WHERE load_strt_dtm + 5 > SYSDATE
but the following will not:
WHERE SYSDATE - load_start_dtm < 5
the reason being that TIMESTAMP arithmetic produces an INTERVAL rather than a NUMBER.
first convert two dates to same format select datediff(dd,convert(varchar(20),'2015-01-01',112),convert(varchar(20),'01-10-2015',112))

convert date to integer in postgresql

I'm trying to convert a date (date type) into int. This int should be something like the number of days since the 1 January 1900. How to get this in postgresql? In excel I'm getting this automatically when i concatenate a date with a string.
Example : 2011/11/01 convert into int as 36831
Simply subtract the two dates:
select date '2011-11-01' - date '1900-01-01'
the result will be the number of days.
More details in the manual:
http://www.postgresql.org/docs/current/static/functions-datetime.html

Oracle - Selecting employees which were hired in the last 20 years

I cannot use months_between, only playing with DATEs is allowed, so I got this:
select * from emp
where ((SYSDATE- hiredate)/(365+1/4-1/100+1/400)) >= ((SYSDATE/(365+1/4-1/100+1/400))-20);
I dont understand why i get error in
(SYSDATE/(365+1/4-1/100+1/400))-20
saying it is an invalid datatype "inconsistent datatypes: expected %s got %s" when
(SYSDATE-hiredate)/(365+1/4-1/100+1/400)
is working properly with no error, WTF?
PS: an example of using (365+1/4-1/100+1/400) is with birth date, for more precision:
((SYSDATE- birth_date)/(365+1/4-1/100+1/400)) >=18
sysdate retuns the current date and time.
In your second test case as below, you are subtracting two dates which returns
numeric value indicating the number of days between the two dates and so calculation (division was made possible).
(SYSDATE-hiredate)/(365+1/4-1/100+1/400)
In your first test case as below, you are directly trying to divide a date type value.
you cannot divide a date datatype in oracle. Instead you can add any value say x (sysdate +x), it means you are adding x days to the date value.
(SYSDATE/(365+1/4-1/100+1/400))-5
In case, you want to convert the sysdate to number you can try like below
select to_number(to_char(sysdate, 'yyyymmddhh24miss')) from dual;
Which will return you DATE+TIME like 20140608165750 for today.
(OR)
select to_number(to_char(sysdate, 'yyyymmdd')) from dual;
Result will be 20140608 (only the DATE part)
According to Oracle on subtracting two Date datatypes you'll get a Number datatype.
From Oracle docs: Reference
So this part of your query
((SYSDATE- birth_date)/(365+1/4-1/100+1/400)) >=18 returns a number, whereas
In this statement (SYSDATE/(365+1/4-1/100+1/400))-5 sysdate is still taken as a date dataype which is why you're getting the error. You can explicitly use to_number to convert sysdate into number.
Edit: Try this ((to_number(to_char(SYSDATE,'DDMMYYYY'))/(365+1/4-1/100+1/400))-5) to convert your sysdate date dataype into number datatype. So, your select query should look like this
select * from emp
where ((SYSDATE- hiredate)/(365+1/4-1/100+1/400)) >= ((to_number(to_char(SYSDATE,'DDMMYYYY'))/(365+1/4-1/100+1/400))-5);