How to extract year from interval in postgres - sql

I found out that the following line:
select extract(year from '2021-01-01'::timestamp - '2020-01-01');
returns 0.
Even if we go a bit further:
select extract(year from '2021-01-01'::timestamp - '2010-01-01');
The result is still 0.
I understand the rationale behind this. If we run a query to check the interval between consecutive New Years:
select '2021-01-01'::timestamp - '2020-01-01';
We're getting the following result:
0 years 0 mons 366 days 0 hours 0 mins 0.00 secs
1 year wouldn't be precise enough - it can mean 365 or 366 days.
Question: Is there an elegant method to retrieve year count from interval being the difference between two timestamps? Something like the first query, where I would expect result as 1.

You should use AGE instead of the difference:
SELECT EXTRACT(YEAR FROM AGE('2021-01-01'::TIMESTAMP, '2010-01-01'::TIMESTAMP));
date_part
-----------
11
See: https://www.postgresql.org/docs/current/functions-datetime.html
Subtract arguments, producing a “symbolic” result that uses years and months, rather than just days

Related

Difference in datetime stamps impala

I want a query that shows a time difference in months or days in Impala
How can I do this?
start 2017-11-29 19:45:00 - end 2018-11-29 21:30:00
I know that month_between and datediff shows the month of datediff but how do I make it so it also takes the year into count when counting the days / months?
For the above example, I want to to display either
month_between - 12.2 months - equivalent to the month calculation of the timestamp - might be a little off cause I did it by hand / 30 days
days_between - 366 days
not sure if you tried DATEDIFF or not , but it already gives you the dates difference in days :
select datediff(endddaate, startdate)
from tablename

Convert arbitrary string values to timestamps SQL

I am wondering if there is a way to convert arbitrary string values (such as the examples below) to something that can be interpreted as a timestamp, perhaps in days.
Dropdown_values
Desired Output(days)
12 weeks
84
1 Week 4 Days
11
1 Year
365
1 Year 1 Week 2 Days
374
The idea I had was to split part out the values since they are all separated by spaces and then do the addition in a separate column, are there other (better) ways to do this? Thank you.
To expand on my comment as an answer:
select extract(epoch from '12 Week'::interval)/86400; 84
select extract(epoch from '1 Year 1 Week 2 Days'::interval)/86400; 11
select extract(epoch from '1 Year 1 Week 2 Days'::interval)/86400; 374.25
The above is how I usually deal with this sort of thing. Extract the epoch value from a the interval and then divide by the number of seconds in a day. It would be a good idea to read in the docs this Interval input and Interval output to understand how an interval is constructed and returned and the assumptions used. Note: the queries will return a float value not a timestamp. A value like 84 cannot be timestamp. You could turn it into an interval like: 84 * '1 day'::interval 84 days. If at all possible it is good idea to store data as actual timestamps(start and end) and then derive intervals from that.

How to Find the Interval Between Two Dates in PostgreSQL

I have a 'test_date' column in 'test' table in Postgres DB, ex - (2018-05-29)
I need to calculate difference between current date and that date column and return the result as days, months, years.
I tried -
select (current_date - test_date) from test;
but it returns the values as days. but I need the result as days, months, years.
How to convert it properly ?
The age() function returns the value as an interval rather than the number of days:
select age(current_date, test_date)
If you use a timestamp then you'll get a `interval' back:
select justify_interval(date_trunc('day', current_timestamp) - test_date)
The date_trunc() is there to set the time part of the timestamp to 00:00:00. By default that would return an interval with only days in it. The justify_interval() will then "normalize" this to months, weeks and days.
E.g. 0 years 7 mons 28 days 0 hours 0 mins 0.0 secs

How to get how many days passed since start of this year?

I have a query which uses needs to know how many days passed since 1st of January in the current year.
Which means that if the query runs for example in:
2nd Jan 2017 than it should return 2 (as 2 days passed since 1st Jan
2017).
10th Feb 2016 than it should return 41 (as 41 days passed since 1st
Jan 2016).
basically it needs to take Current Year from Curent Date and count the days since 1/1/(Year).
i have the current year with: SELECT EXTRACT(year FROM CURRENT_DATE);
I created the 1st of Jan with:
select (SELECT EXTRACT(year FROM CURRENT_DATE)::text || '-01-01')::date
How do I get the difference from this date to Current_Date?
Basically this question can be Given two dates, how many days between them?
Something like age(timestamp '2016-01-01', timestamp '2016-06-15') isn't good because I need the result only in days. while age gives in years,months and days.
An easier approach may be to extract the day of year ("doy") field from the date:
db=> SELECT EXTRACT(DOY FROM CURRENT_DATE);
date_part
-----------
41
And if you need it as a number, you could just cast it:
db=> SELECT EXTRACT(DOY FROM CURRENT_DATE)::int;
date_part
-----------
41
Note: The result 41 was produced by running the query today, February 9th.
Given two dates, how many days between them
Just subtract one from the other.
In your case you could just round the current_date to the start of the year and subtract that from the current date:
select current_date - date_trunc('year', current_date)::date
The ::date cast is necessary to get the result as an integer, otherwise the result will be an interval.
Another solution is to use DATEDIFF
SELECT DATE_PART('day', now()::timestamp - '2016-01-01 00:00:00'::timestamp);

Hive - How do I get last months of data from Hive?

How do I get last 2 months of data from Hive?
Here is my attempt:
select (date_add(FROM_UNIXTIME(UNIX_TIMESTAMP(), 'yyyy-MM-dd'),
2 - month(FROM_UNIXTIME(UNIX_TIMESTAMP(), 'yyyy-MM-dd'))
));
This results in 2015-05-30. The results should be like: if Today is '2015-06-03', then the result of last two months should be like: '2015-04-01'. Notice that I put the first day of the month for the results. What am I doing wrong here? Thanks!
Extra Notes:
In SQL is it pretty easy to get:
select * from date_field >= DATEADD(MONTH, -2, GETDATE());
date_add adds days, not months. The below line evaluates to -4
2 - month(FROM_UNIXTIME(UNIX_TIMESTAMP(), 'yyyy-MM-dd'))
So you are basically subtracting 4 days from '2015-06-03', which is why you get the result '2015-05-30'.
As far as I know, there is no direct way to subtract months in Hive. Solutions you could consider:
Subtract 60 days, but that won't give you accurate results.
Write a custom UDF to return the date 2 months ago.
Calculate the date in a script, and pass it to hive.