SELECT past hour data - postgresql

I have a simple database
id name value date time
1 box 34 2020-06-08 14:45:00
2 box 35 2020-06-08 15:00:00
3 box 4 2020-06-08 15:15:00
4 box 44 2020-06-08 15:30:00
5 box 42 2020-06-08 15:45:00
6 box 41 2020-06-08 16:00:00
7 box 0 2020-06-08 16:15:00
8 box 0 2020-06-08 16:30:00
9 box 0 2020-06-08 16:45:00
...
I am trying to retrieve the latest past 1 hour data from a Postgresql database. The objective is to run this query every hour to get the past one hour data for further processing in another software.
The records in the database already contain all the timestamps for the day (15 minutes interval).
Therefore, from the example, assuming my local time is 16:00:00, I will want to take the past 1 hour data from my local time.
I have tried the following:
SELECT id, name, value, date, time
FROM boxbox
WHERE time >= (NOW() - INTERVAL '1 hour')
ORDER BY time desc
But I am getting this SQL error
SQL Error [42883]: ERROR: operator does not exist: time without time zone >=
timestamp with time zone
The table datatype is as follow:
id - int4
name - varchar
value - int
date - date
time - time
Thank you.

Well, now() returns a timestamp with time zone, not a time value. And you can't compare a time value with a timestamp with time zone value.
You need to use localtime:
SELECT id, name, value, "date", "time"
FROM boxbox
WHERE "time" >= localtime - INTERVAL '1 hour'
ORDER BY "time" desc
However the above won't work properly if the time crossed midnight. If you also need to take care of that, you need to combine your date and time columns to a single timestamp column:
SELECT id, name, value, "date", "time"
FROM boxbox
WHERE "date" + "time" >= now () - INTERVAL '1 hour'
ORDER BY "time" desc

Related

How to do JOIN query on column having epoch value ignoring the time part in postgres

I have two tables lets say tableA and tableB , both the tables have a columnn creation_date having epoch value in it. I want to join these two tables on creation_date ignoring the time value in it.
Lets say if the epoch value is 1603385466134 which translates to Thu Oct 22 2020 22:21:06. Now the join should happen as Thu Oct 22 2020 00:00:00
I Tried this but not working
Select t.lr_transaction_id, t.unique_customer_id, t.transaction_id
from boidcrewardz.transaction_temp t
join boidcrewardz.transaction_dump d
on t.first_6_digit_card = d.first_6_digit_card
and t.transaction_amount = d.transaction_amount
and date_trunc('day',t.transaction_date) = date_trunc('day',d.transaction_date)
order by t.creation_date desc
Postgres 9 and later supports to_timestamp():
to_timestamp ( double precision ) → timestamp with time zone
Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp
with time zone
to_timestamp(1284352323) → 2010-09-13 04:32:03+00
Postgres 8 supports SELECT TIMESTAMP WITH TIME ZONE 'epoch' + 1603385466.134 * INTERVAL '1 second'
You just need to divide your epoch value by 1000.00 as your epoch is counting milliseconds while Postgres expects seconds.
One of the following should work:
select date_trunc('day',to_timestamp(1603385466134/1000.00));
SELECT date_trunc('day',TIMESTAMP WITH TIME ZONE 'epoch' + 1603385466134/1000.00 * INTERVAL '1 second');

Calendar days since date in days

Given the following sqlfiddle: http://www.sqlfiddle.com/#!17/f483a/2/0
create table test (
start_date date
);
insert into test values ('2019/01/01');
select
start_date,
age(now()::date,start_date) as date_diff
from test;
Which generates the following output:
date_diff | 0 years 7 mons 27 days 0 hours 0 mins 0.00 secs
How could I instead generate the correct number of calendar days
239 days
without using a custom function?
Don't use the age function. Subtracting a date from a date yields an integer. now() returns a timestamp so you need to use current_date instead.
select start_date,
current_date - start_date as date_diff
from test;

postgresql query for hour minutes and seconds

Hi I am having a Postgresql query like below to calculate DateTime difference for {1} and {2} in minutes.
CAST(ROUND(EXTRACT(EPOCH from (({2}::timestamp) - ({1}::timestamp)))/60) AS INT)
I want to calculate the difference in hours, minutes and seconds displayed like:
3 hrs 31 minutes 42 secs
What manipulation do I need for displaying like above?
SELECT to_char((col1 - col0), 'HH24 hrs MI "minutes" SS "seconds"') FROM T1;
Here is a sqlfiddle : link
The to_char function takes an interval (an interval is the time span between two timestamps, and subtracting timestamps gives you an interval). It then takes a formatting, and you can apply pretty much what you want.
Formatting functions in PostgreSQL
Try use this sql:
SELECT to_char(column2 - column1, 'DD" days "HH24" hours "MI" minutes "SS" seconds"');
The subtraction of two timestamp or timestamptz values produces an interval. (While subtracting two date values produces an integer!)
Details about date/time types in the manual.
The default text representation of an interval may be sufficient:
SELECT timestamp '2017-1-6 12:34:56' - timestamp '2017-1-1 0:0';
Result is an interval, displayed as:
5 days 12:34:56
If you need the format in the question, precisely, you need to specify how to deal with intervals >= 24 hours. Add 'days'? Or just increase hours accordingly?
#Nobody provided how to use to_char(). But add days one way or the other:
SELECT to_char(ts_col2 - ts_col1, 'DD" days "HH24" hours "MI" minutes "SS" seconds"');
Result:
05 days 12 hours 34 minutes 56 seconds
'days' covers the rest. There are no greater time units in the result by default.
Simple
SELECT
EXTRACT(year FROM LOCALTIMESTAMP(0) - yourFieldTime)||' year '||
EXTRACT(month FROM LOCALTIMESTAMP(0) - yourFieldTime)||' month '||
EXTRACT(day FROM LOCALTIMESTAMP(0) - yourFieldTime)||' day '||
EXTRACT(hour FROM LOCALTIMESTAMP(0) - yourFieldTime)||' hour '||
EXTRACT(minute FROM LOCALTIMESTAMP(0) - yourFieldTime)||' minute '||
EXTRACT(second FROM LOCALTIMESTAMP(0) - yourFieldTime)||' second '
AS full_time_as_you_wish FROM your_table;
Result
full_time_as_you_wish
---------------------------------
0 year 0 month 0 day 0 hour 0 minute 0 second

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;

Retrieving the start and end hour queries correctly in PostgreSQL Query

I have a CTE-based query in which I retrieve hourly intervals between two given timespans. My query works as following:
Getting start and end datetimes (let's say 07-13-2011 00:21:09 and 07-31-2011 21:11:21)
get the hourly total query values between the hourly intervals (in here it's from 00 to 21, a total of 21 hours but this is parametric and depends on the hours I give for the inputs) for each day. This query works well but there is a problem. It displays hourly amounts but for the start time, it gets all the queries between 00:00:00 and 00:59:59 for each day instead of 00:21:09 - 00:59:59 and same applies for the end time, it gets all the queries between 21:00:00 and 22:00:00 for each day instead of 21:00:00 and 21:11:21. -By the way, the other hour intervals e.g 03:00 - 04:00 etc are currently retrieved normally, no minute and seconds provided, just 1 hour flat intervals- How can I fix that? The query is below, thanks.
WITH cal AS (
SELECT generate_series('2011-02-02 00:00:00'::timestamp , '2012-04-01 05:00:00'::timestamp , '1 hour'::interval) AS stamp
)
, qqq AS (
SELECT date_trunc('hour', calltime) AS stamp
, count(*) AS zcount
FROM mytable
WHERE calltime >= '07-13-2011 00:21:09' AND calltime <='07-31-2011 21:11:21' AND date_part('hour', calltime) >= 0 AND date_part('hour', calltime) <= 21
GROUP BY date_trunc('hour', calltime)
)
SELECT cal.stamp
, COALESCE (qqq.zcount, 0) AS zcount
FROM cal
LEFT JOIN qqq ON cal.stamp = qqq.stamp
WHERE cal.stamp >= '07-13-2011 00:00:00' AND cal.stamp<='07-31-2011 21:11:21' AND date_part('hour', cal.stamp) >= 0 AND date_part('hour', cal.stamp) <= 21
ORDER BY stamp ASC;
EDIT:
What I mean with my problem is, despite giving 00:21:09 for my starting hour on first day, the days after that day calculate the total query count for the first hour interval as count of total queries between 00:00:00-01:00:00 instead of 00:21:09-01:00:00.(by the way this should apply to the first hour interval for every day, I can give 04:30:21 for the starting hour and the day will start to count total queries hourly starting from there etc.- Same applies to the ending hour 21:00:00-21:11:21, only the LAST day in the query results take this interval, other days before it take the query count between hour 21 and 22 by counting all queries between 21:00:00-22:00:00 instead of 21:00:00-21:11:21.
For example, if there are 200 queries between 00:00:00 and 01:00:00 on july 14 2011 (the next day after july 13, the start date) but there are 159 queries between 00:21:09 - 01:00:00, I should get 159 queries instead of 200. Also, if there are 300 queries between 21:00:00-22:00:00 on any random day, and 123 of them are between 21:00:00-21:11:21, I should get 123 queries as result instead of 300. (This applies to every single day, other hourly intervals should be counted as usual such as 01:00-02:00, 20:00-21:00 etc. This is parametric, hourly intervals and start-end times depend on user input-
Adding AND calltime::time >= '00:21:09' AND calltime::time <= '21:11:21' to the WHERE calltime >= '07-13-2011 00:21:09' AND calltime <='07-31-2011 21:11:21' block solved the issue.