Postgresql timestamp difference greater than 1 hour - postgresql

Hi I have a entrytime and exittime timestamp in my database, how can I query it to display only ones where the person exited more than an hour later;
Select * from store where EXTRACT(EPOCH FROM (exittime - entrytime))/3600 >60
That's what I have so far but it won't work, any help would be appreciated.

Just subtract the values and compare it with an interval
Select *
from store
where exittime - entrytime > interval '1 hour';
This assumes that both columns are defined as timestamptz or timestamp

Related

Last 7 days from postgres table epoch timestamp

I have a table (funny_quotes) which has a column called quote_date and it stores data in unix epoch time (seconds)
I want to run a query to only return data from this table(funny_quotes) only from the last 3 days.
I created a table locally in postgres but unable to store dates as epoch time, they only get stored as timestamp values
select * from funny_quotes where quote_date > (now() - interval '3 days')
You should modify the right side of the equation to epoch in order to be able to compare:
select * from funny_quotes where quote_date > extract(epoch from (now() - interval '3 days'))
Or the other way around: convert quote_date into timestamp:
select * from funny_quotes where to_timestamp(quote_date) > now() - interval '3 days'
You can read more about it in the docs

How to truncate a date to the beginning of week (Sunday)?

I need to truncate dates to the start of week, which is Sunday in my case. How can I do this in PostgreSQL? This truncates to Monday:
date_trunc('week', mydate)
If you subtract the dow value (0 for Sundays, 6 for Saturdays) from the current date than you get the previous Sunday which is the begin of your Sunday-based week
demo:db<>fiddle
SELECT
my_date - date_part('dow', my_date)::int
FROM
my_table
Further reading, documentation
You could truncate the date to the week's Monday, then subtract 1 day, e.g:
SELECT (date_trunc('week', now() + interval '1 day') - interval '1 day')::DATE;
date
------------
2019-06-16
As per documentation, date_trunc() accepts values of type date and timestamp and returns a timestamp (thus the cast at the end).

How to cast an int of microseconds into a interval field in postgres?

There is this question about how to extract microseconds from an interval field
I want to do the opposite, I want to create an interval from a numeric microseconds. How would I do this?
The reason is I want to take a table of this format
column_name | data_type
-------------+--------------------------
id | bigint
date | date
duration | numeric
and import it into a table like this
column_name | data_type
-------------+--------------------------
id | integer
date | date
duration | interval
Currently I am trying:
select CAST(duration AS interval) from boboon.entries_entry;
which gives me:
ERROR: cannot cast type numeric to interval
LINE 1: select CAST(duration AS interval) from boboon.entries_entry;
You can do:
select duration * interval '1 microsecond'
This is how you convert any date part to an interval in Postgres. Postgres supports microseconds, as well as more common units.
you can append the units and then cast to interval
example:
select (123.1234 || ' seconds')::interval
outputs:
00:02:12.1234
valid units are the following (and their plural forms):
microsecond
millisecond
second
minute
hour
day
week
month
quarter
year
decade
century
millennium

Ignoring seconds from timestamp postgres

I am running a cron job every 1 minute for notifying users for events
select * from events where event_start = now() - interval '30 minutes'
so that I can send the users a notification prior to 30 mins of event
problem is event start is a timestamp field so if there is a difference in seconds it this wll not work ,so how can ignore the seconds part .
You can use date_trunc() to remove the seconds:
select *
from events
where event_start = date_trunc('second', now()) - interval '30' minutes
More details in the manual: http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
In order to ignore seconds, you can use date_trunc() function.
The function date_trunc is conceptually similar to the trunc function
for numbers.
date_trunc(field, source [, time_zone ]) source is a value expression
of type timestamp, timestamp with time zone, or interval. (Values of
type date and time are cast automatically to timestamp or interval,
respectively.) field selects to which precision to truncate the input
value. The return value is likewise of type timestamp, timestamp with
time zone, or interval, and it has all fields that are less
significant than the selected one set to zero (or one, for day and
month).
Valid values for field are:
microseconds
milliseconds
second
minute
hour
day
week
month
quarter
year
decade
century
millennium
SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-02-16 20:00:00
SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-01-01 00:00:00
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
Result: 2001-02-16 00:00:00-05
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney');
Result: 2001-02-16 08:00:00-05
SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
Result: 3 days 02:00:00
So in your case, you should use:
SELECT *
FROM events
WHERE event_start = date_trunc('minute', now()) - INTERVAL '30' MINUTE;

Dynamic (Column Based) Interval

How do I add a dynamic (column based) number of days to NOW?
SELECT NOW() + INTERVAL a.number_of_days "DAYS" AS "The Future Date"
FROM a;
Where a.number_of_days is an integer?
I usually multiply the number by interval '1 day' or similar, e.g.:
select now() + interval '1 day' * a.number_of_days from a;
I know this is a year old, but if you need to use a column to specify the actual interval (e.g. 'days', 'months', then it is worth knowing that you can also CAST your string to an Interval, giving:
SELECT now()+ CAST(the_duration||' '||the_interval AS Interval)
So the the original question would become:
SELECT now() + CAST(a.number_of_days||" DAYS" AS Interval) as "The Future Date" FROM a;
I prefer this way. I think its pretty easy and clean.
In Postgres you need interval to use + operator with timestamp
select (3||' seconds')::interval;
select now()+ (10||' seconds')::interval,now();
where you can use seconds, minutes, days, months...
and you can replace the numbers to your column.
select now()+ (column_name||' seconds')::interval,now()
from your_table;
Use make_interval()
SELECT NOW() + make_interval(days => a.number_of_days) AS "The Future Date"
FROM a;
But in general it might be a better idea to use a column defined as interval, then you can use any unit you want when you store a value in there.
To creating intervals those based on column values, I recommend to add two columns in your table. For example, column "period_value"::INT4 and column "period_name"::VARCHAR.
Column "period_name" can store the following values:
microsecond
milliseconds
second
minute
hour
day
week
month
quarter
year
decade
century
millennium
+--------------+-------------+
| period_value | period_name |
+--------------+-------------+
| 2 | minute |
+--------------+-------------+
Now you can write:
SELECT NOW() - (period_value::TEXT || ' ' || period_name::TEXT)::INTERVAL FROM table;
If we have field with interval string value such as '41 years 11 mons 4 days' and want to convert it to date of birth use this query :
UPDATE "february14" set dob = date '2014/02/01' - (patient_age::INTERVAL)
dob is date field to convert '41 years 11 mons 4 days' to '1972/10/14' for example
patient_age is varchar field that have string like '41 years 11 mons 4 days'
And this is query to convert age back to date of birth
SELECT now() - INTERVAL '41 years 10 mons 10 days';
Updating based on a column ID was a useful way to create some randomised test data for me.
update study_histories set last_seen_at = now() - interval '3 minutes' * id;