Postgres Time Difference - postgresql

I am trying to retrieve time difference in minutes from a table(login_history as t1) using postgresql .
When i tried this code
((date_part('hour', timestamp '2014-04-25 09:44:21')- date_part('hour', timestamp '2014-04-25 08:32:21'))*60 +(date_part('minutes', timestamp '2014-04-25 09:44:21')- date_part('minutes', timestamp '2014-04-25 08:32:21'))) as TimeNew
It works fine.
But when i tried to retrieve information from a table t1 using this code
((date_part('hour', timestamp t1.login_date)- date_part('hour', timestamp t1.logout_date))*60 +
(date_part('minutes', timestamp t1.login_date)- date_part('minutes', timestamp t1.logout_date))
) as TimeNew
It throws this error
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "t1"
Thanks

I would use the interval that results from subtracting two timestamps for a much simpler expression:
select extract (epoch from (timestamp '2014-04-25 09:44:21' - timestamp '2014-04-25 08:32:21'))::integer/60
(gives 72)
or for your table:
select extract (epoch from (t1.logout_date - t1.login_date))::integer/60
If you need to cast:
select extract (epoch from (t1.logout_date::timestamp - t1.login_date::timestamp))::integer/60
or see the to_timestamp function for custom string parsing: http://www.postgresql.org/docs/9.4/static/functions-formatting.html

I needed to remove the timestamp from the query before t1 and the query works.

Related

PostgreSQL query for elapsed interval

I am trying to query PostgreSQL database for rows where interval has elapsed from the last run. Main columns for this purpose are processed_at as timestamptz and frequency (in minutes) as integer.
I am failing with operators, since not many of them can operate together timestamp & integer.
Can someone please propose a query that would solve this? Thank you very much for help
From here Date/time operators:
timestamp + interval → timestamp
Add an interval to a timestamp
timestamp '2001-09-28 01:00' + interval '23 hours' → 2001-09-29 00:00:00
select now() + (10::varchar || ' min')::interval;
?column?
-------------------------------
2021-10-15 09:05:37.927163-07
--Or in your case. If I'm following you are adding the interval.
select processed_at + (frequency::varchar || ' min')::interval;
The query takes the integer value of minutes and converts it to an interval of minutes that can be added to the timestamp.
Further explanation, || is the Postgres concatenation operator and ::varchar, ::interval are casting shorthand.
UPDATE
I keep forgetting about the make_*() functions for date/time/interval
--A shorter version
select processed_at + make_interval(mins => frequency);
Saves all the casting.

text to timestamp in postgresql

In the view I have a text column which contains a timestamp in this format '20/03/2018 00:00' and I'm trying to make a selection with a between clause but it's not working
SELECT id,entry_date
FROM v_view
WHERE entrada BETWEEN to_timestamp('20/03/2018 00:00','DD/MM/YYYY')::timestamp and to_timestamp('22/03/2018 00:00')::timestamp
order entry_date
with this error message
ERROR: el operador no existe: text >= timestamp without time zone
LINE 3: WHERE entry_date BETWEEN to_timestamp('20/03/2018 00:00','DD/MM.
you need to convert the entrada column value to a timestamp.
Also: casting the result of to_timestamp() to a timestamp is useless because to_timestamp() already returns a timestamp
SELECT id,entry_date
FROM v_view
WHERE to_timestamp(entrada, 'dd/mm/yyyy hh24:mi')
BETWEEN to_timestamp('20/03/2018', 'DD/MM/YYYY')
and to_timestamp('22/03/2018', 'dd/mm/yyyy')
order entry_date;
I prefer to use ANSI SQL timestamp literals over the to_timestamp function:
SELECT id,entry_date
FROM v_view
WHERE to_timestamp(entrada, 'dd/mm/yyyy hh24:mi')
BETWEEN timestamp '2018-03-20 00:00:00'
and timestamp '2018-03-22 00:00:00'
order entry_date
Do not store date, time or timestamp values in a text or varchar column. You should define that column as timestamp then you don't need to convert anything and you don't need to deal with invalid timestamp values in that column.

How to handle timestamp with timezone on postgres with knex.js

I am trying to translate following sql query into knex:
select count(*) as finished_on_time from task_history
where date = 20160303
and store_id = 2
and (schedule_start_time at time zone 'Australia/sydney' + interval '1' minute * floor (group_duration) )::time >= (finish_time at time zone 'Australia/sydney')::time
date field has in yyyymmdd format
Here is what I have been trying on knex:
db.table('task_history')
.count('*')
.where({date: request.params.storeid, store_id: request.params.storeid })
??????
As you can guess, I am not sure which clause to use to handle sql syntax [at time zone Australia/sydney].
I have been trying to find any similar soloutions on the internet, but ended up here.
http://knexjs.org/#Builder-whereRaw
db.table('task_history')
.count('*')
.where({date: request.params.storeid, store_id: request.params.storeid })
.whereRaw("(schedule_start_time at time zone 'Australia/sydney' + interval '1' minute * floor (group_duration) )::time >= (finish_time at time zone 'Australia/sydney')::time")

SUM Data if Duplicate in Postgres

I am having table with three columns and may have duplicate data in it. what I am trying to do is if BATCH Column is having Duplicate Data then START_S and END_S should be according to below Example
CREATE TABLE "DRL_FTO3_DI1_A0_BATCH"
(
"BATCH" character varying(128),
"START_S" integer,
"END_S" integer
)
INSERT INTO "DRL_FTO3_DI1_A0_BATCH"(
"BATCH", "START_S", "END_S")
VALUES ('Batch 1_1',1451120920,1451121008),
('Batch 01_2',1451389014,1451389100),
('Batch 2_1',1451534680,1451534918),
('Batch 3_1',1451539145,1451539264),
('Parth_2',1451540990,1451541285),
('Parth_2',1451541676,1451542254)
SELECT "BATCH",((TIMESTAMP WITHOUT Time Zone 'epoch' + "START_S" * INTERVAL '1 second') AT TIME ZONE 'UTC')::TIMESTAMP WITHOUT Time Zone,
((TIMESTAMP WITHOUT Time Zone 'epoch' + "END_S" * INTERVAL '1 second') AT TIME ZONE 'UTC')::TIMESTAMP WITHOUT Time Zone
FROM "DRL_FTO3_DI1_A0_BATCH"
Now as we can see Parth_2 is duplicate value so START_S and END_S for Parth_S should be
Parth_2 2015-12-31 11:19:50 2015-12-31 11:40:54
You could do it using GROUP BY and MIN/MAX aggregate functions (you can convert into date time later with below query in format you desire) like:
SELECT BATCH, MIN(START_S), MAX(END_S)
FROM DRL_FTO3_DI1_A0_BATCH
GROUP BY BATCH

How can I have timestamp displayed in UTC+02 (same timezone) for both the queries below?

My first query is:
SELECT distinct wfc_request_job_id,wfc_request_job_info,
replace(iso_cc,';',' ') as "iso_cc",to_char(wfc_request_start_ts,'yyyy-MM-dd HH:mm:ss') as ts,
sent_message_count,
(link_object_count + poi_object_count + point_address_object_count) as request_object_count
FROM wfc_request_job
where
wfc_request_job_id=173526;
This returns ts as 2015-08-16 03:08:59
Second Query:
SELECT wfc_request_job_id,wfc_request_start_ts,wfc_request_end_ts,replace(iso_cc,';',' ') as "iso_ccs",sent_message_count,wfc_queue_name
FROM wfc_request_job
where
to_char(wfc_request_start_ts,'YYYY-MM-DD') >= to_char(to_date('08/16/2015','MM/DD/YYYY'),'YYYY-MM-DD')
and to_char(wfc_request_start_ts,'YYYY-MM-DD') <= to_char(to_date('08/16/2015','MM/DD/YYYY'),'YYYY-MM-DD')
order by wfc_request_job_id desc
This returns ts of the job id mentioned above as - "2015-08-16 15:58:59.809+02"
How can I make both the queries return ts in UTC+02 - i.e. same timezone
The data type of wfc_request_start_ts is - timestamp with timezone
I changed to queries to have the format HH24:MI:SS however that did not help. Please note that the webapp using these queries will be opened in both Germany and USA.
According to postgresql manual to_char there is TZ (and OF as of v9.4) template patterns for Date/Time formatting.
Therefore in query you need to add it so
postgres=# select to_char(now(),'yyyy-MM-dd HH24:mm:ss TZ');
to_char
------------------------
2015-08-19 12:08:56 CEST
(1 row)
Also, make sure you specify timezone when converting
so instead
to_date('08/16/2015','MM/DD/YYYY')
use
TIMESTAMP WITH TIME ZONE '2015-08-16 00:00:00+02';
in second query.