Addition of timestamp is not working in redshift - amazon-redshift

select CAST(current_date as timestamp)
+ to_char(timestamp '2019-07-08 09:00:00','YYYY-MM-DD HH24:MI:SS')::TIMESTAMP;
Current output: 2019-08-02 00:00:002019-07-08 09:00:00

You can use the DATEADD() function or the INTERVAL syntax to add specific units of time to another date/timestamp.
SELECT DATEADD(hour, 9, current_date);
-- date_add
-- ---------------------
-- 2019-08-05 09:00:00
SELECT current_date + INTERVAL '9 hours';
-- ?column?
-- ---------------------
-- 2019-08-05 09:00:00

Related

Group by Date and sum of total duration for that day

I am using workbench/j Postgres DB for my query which is as follows -
Input
ID |utc_tune_start_time |utc_tune_end_time
----------------------------------------------
A |04-03-2019 19:00:00 |04-03-2019 20:00:00
----------------------------------------------
A |04-03-2019 23:00:00 |05-03-2019 01:00:00
-----------------------------------------------
A |05-03-2019 10:00:00 |05-03-2019 10:30:00
-----------------------------------------------
Output
ID |Day |Duration in Minutes
----------------------------------------
A |04-03-2019 |120
-----------------------------------
A |05-03-2019 |90
-----------------------------------
I require the duration elapsed from the utc_tune_start_time till the end of the day and similarly, the time elapsed for utc_tune_end_time since the start of the day.
Thanks for your clarifications. This is possible with some case statements. Basically, if utc_tune_start_time and utc_tune_end_time are on the same day, just use the difference, otherwise calculate the difference from the end or start of the day.
WITH all_activity as (
select date_trunc('day', utc_tune_start_time) as day,
case when date_trunc('day', utc_tune_start_time) =
date_trunc('day', utc_tune_end_time)
then utc_tune_end_time - utc_tune_start_time
else date_trunc('day', utc_tune_start_time) +
interval '1 day' - utc_tune_start_time
end as time_spent
from test
UNION ALL
select date_trunc('day', utc_tune_end_time),
case when date_trunc('day', utc_tune_start_time) =
date_trunc('day', utc_tune_end_time)
then null -- we already calculated this earlier
else utc_tune_end_time - date_trunc('day', utc_tune_end_time)
end
FROM test
)
select day, sum(time_spent)
FROM all_activity
GROUP BY day;
day | sum
---------------------+----------
2019-03-04 00:00:00 | 02:00:00
2019-03-05 00:00:00 | 01:30:00
(2 rows)

How do I generate months between start date and now() in postgresql

I also have the question how do i get code block to work on stack overflow but that's a side issue.
I have this quasi-code that works:
select
*
from
unnest('{2018-6-1,2018-7-1,2018-8-1,2018-9-1}'::date[],
'{2018-6-30,2018-7-31,2018-8-31,2018-9-30}'::date[]
) zdate(start_date, end_date)
left join lateral pipe_f(zdate...
But now I want it to work from 6/1/2018 until now(). What's the best way to do this.
Oh, postgresql 10. yay!!
Your query gives a list of first and last days of months between "2018-06-01" and now. So I am assuming that you want to this in a more dynamic way:
demo: db<>fiddle
SELECT
start_date,
(start_date + interval '1 month -1 day')::date as end_date
FROM (
SELECT generate_series('2018-6-1', now(), interval '1 month')::date as start_date
)s
Result:
start_date end_date
2018-06-01 2018-06-30
2018-07-01 2018-07-31
2018-08-01 2018-08-31
2018-09-01 2018-09-30
2018-10-01 2018-10-31
generate_series(timestamp, timestamp, interval) generates a list of timestamps. Starting with "2018-06-01" until now() with the 1 month interval gives this:
start_date
2018-06-01 00:00:00+01
2018-07-01 00:00:00+01
2018-08-01 00:00:00+01
2018-09-01 00:00:00+01
2018-10-01 00:00:00+01
These timestamps are converted into dates with ::date cast.
Then I add 1 month to get the next month. But as we are interested in the last day of the previous month I subtract one day again (+ interval '1 month -1 day')
Another option that's more ANSI-compliant is to use a recursive CTE:
WITH RECURSIVE
dates(d) AS
(
SELECT '2018-06-01'::TIMESTAMP
UNION ALL
SELECT d + INTERVAL '1 month'
FROM dates
WHERE d + INTERVAL '1 month' <= '2018-10-01'
)
SELECT
d AS start_date,
-- add 1 month, then subtract 1 day, to get end of current month
(d + interval '1 month') - interval '1 day' AS end_date
FROM dates

Postgres expand time window using date_part

Have two dates - '2018-05-01' and '2018-06-01'. I would like to expand this window to the past by day difference of those dates.
SELECT * FROM data
WHERE
start_time > CAST('2018-05-01' AS timestamptz) - INTERVAL '30 DAY'
AND start_time < CAST('2018-06-01' AS timestamptz)
How can I replace INTERVAL '30 DAY' with number of days between given dates without explicitly defining number of days? I know to calculate day difference:
date_part('day',age('2018-05-01', '2018-06-01'))
But not sure how to incorporate into the substraction. Dates and days between them will change.
You can use date_trunc('mon', some_date_expression) to round down to the start of a month:
select date_trunc('mon', now() - '3 mon'::interval) as date_begin
, date_trunc('mon', now() - '1 day'::interval) as date_end
;
Result
date_begin | date_end
------------------------+------------------------
2018-03-01 00:00:00+01 | 2018-06-01 00:00:00+02
(1 row)
You can simply subtract the difference from the start date:
with t (start_date, end_date) as (
values (date '2018-05-01', date '2018-06-01')
)
select start_date - (end_date - start_date) as new_start,
end_date
from t;
returns
new_start | new_end
-----------+-----------
2018-03-31 | 2018-06-01

Postgresql: add 24 hours on a timestamp

Hi i have to add 24 hours on a timestamp converted from a string in postgres db.
here my code:
select to_timestamp(timestamp_start, 'YYYY-MM-DD HH24:MI:SS.US') + interval '24 hour' as tstamp from tablename
the query works but it adds two 0 at the end of the timestamp: "2017-05-23 17:35:13.105867+00"
why and how to solve it?
+00 meant it is timestamp with timezone and your client timezone is UTC.
If you dont want those +00 on the screen, cast it to timestamp without timezone, eg:
t=# select now();
now
-------------------------------
2017-05-23 09:04:46.105322+00
(1 row)
Time: 0.690 ms
t=# select now()::timestamp;
now
----------------------------
2017-05-23 09:04:51.849522
(1 row)
Time: 0.537 ms
So for query in original post it would be:
select (to_timestamp(timestamp_start, 'YYYY-MM-DD HH24:MI:SS.US') + interval '24 hour')::timestamp as tstamp
from tablename

pgSQL date function

How do I tweak this pgSQL SELECT using pgSQL's date functions so it always returns "01" for the day # and "00:00:00" for the time?
SELECT s.last_mailing + '1 month'::interval AS next_edition_date FROM
last_mailing is defined as
last_mailing timestamp without time zone
Examples of the result I am wanting are:
2015-10-01 00:00:00
2015-11-01 00:00:00
2015-12-01 00:00:00
You're looking for date_trunc().
psql (9.5alpha2, server 9.4.4)
Type "help" for help.
testdb=# create table subscriptions as select 1 "id", '2015-07-14T12:32'::timestamp last_mailing union all select 2, '2015-08-15T00:00';
SELECT 2
testdb=# select * from subscriptions; id | last_mailing
----+---------------------
1 | 2015-07-14 12:32:00
2 | 2015-08-15 00:00:00
(2 rows)
testdb=# select *, date_trunc('month', last_mailing) + interval '1 month' AS next_edition_date from subscriptions;
id | last_mailing | next_edition_date
----+---------------------+---------------------
1 | 2015-07-14 12:32:00 | 2015-08-01 00:00:00
2 | 2015-08-15 00:00:00 | 2015-09-01 00:00:00
(2 rows)
If you want the first day of the next month, then use:
SELECT (s.last_mailing - (1 - extract(day from s.last_mailing)) * interval '1 day') +
interval '1 month' AS next_edition_date
FROM . . .
If you don't want the time, then use date_trunc():
SELECT date_trunc('day',
(s.last_mailing - (1 - extract(day from s.last_mailing)) * interval '1 day') +
interval '1 month'
) AS next_edition_date
FROM . . .