How to work with time interval in postgreSQL - sql

I have a postgreSQL query that returns 'Late' when the given condition is met, currently, When i run below query I'm getting an error
SELECT
CASE WHEN CAST(so.scheduled_delivery_time AS date) < CURRENT_DATE OR CAST(so.scheduled_delivery_time AS date) = CURRENT_DATE AND DATETIME(so.scheduled_delivery_time) < DATETIME_SUB(datetime(current_datetime()), INTERVAL '3' HOUR) THEN 'Late'
END AS status
FROM
table1
Error
ERROR: function datetime(timestamp without time zone) does not exist Hint: No function matches the given name and argument types.
What I'm I missing?

Hey there — the simplest answer is that there is no function named DATETIME. Also it looks like your values are already timestamps, so you can probably just do this:
so.scheduled_delivery_time < current_datetime() - INTERVAL '3' HOUR

A good starting point to find the available functions, is the fine manual. CURRENT_TIMESTAMP will give you the current timestamp and you can use it like this:
SELECT CURRENT_TIMESTAMP;

Related

Add one day to Now() and return as default value in SQL query

I am attempting to add a day to NOW() and return as the values for a column.
This works
SELECT NOW() as date
But this gives an error
SELECT DATE_ADD( NOW(), INTERVAL 1 DAY) as date
Is there a way to achieve this in a postgres query?
Thanks
I don't think there's a date_add() function in PostgreSQL:
ERROR: function date_add(timestamp with time zone, interval) does not
exist
LINE 1: select date_add(now(), interval '1 day');
^
HINT: No function matches the given name and argument types. You
might need to add explicit type casts.
but you can use a regular + operator to add an interval to timestamptz that's returned by now(). Demo:
select now() + '1 day'::interval;
You can define that function for convenience:
create function date_add(arg1 timestamptz, arg2 interval)
returns timestamptz language sql as $$
select arg1+arg2
$$;
select date_add(now(), interval '1 day') as date;
-- date
---------------------------------
-- 2022-11-29 12:28:12.393508+00
But I don't think it's really more convenient than the operator. You'd also have to overload it to make sure how it deals with different types - you can see in the demo how by default PostgreSQL will try to guess and cast automatically.

converting Athena timestamp to date

I am running a query against Athena, and it breaks. Specifically, I get an error for the below fragment:
avg(
DATE_DIFF(
'minute',
CAST(from_iso8601_timestamp("sessions_staging".session_start_at) AS TIMESTAMP),
CASE
WHEN CAST("sessions_staging__end_raw" AS TIMESTAMP) + INTERVAL '1' MINUTE > CAST("sessions_staging".next_session_start_at AS TIMESTAMP) THEN CAST("sessions_staging".next_session_start_at AS TIMESTAMP)
ELSE CAST("sessions_staging__end_raw" AS TIMESTAMP) + INTERVAL '30' MINUTE
END
)
) "sessions_staging__average_duration_minutes"
Athena complains with Value cannot be cast to timestamp: 2022-08-03T00:05:54.300Z.
I tried a bunch of tricks like casting my date to string then casting again to a time or a timestamp type. A similar problem caused by the same issue is covered some in converting to timestamp with time zone failed on Athena
The value seems to be just fine. I am able to execute: SELECT CAST(From_iso8601_timestamp('2022-08-03T00:05:54.300Z') AS timestamp). If I do not use CAST() and just do: "sessions_staging".session_start_at, it says that (varchar(6), varchar, timestamp) for function date_diff so I know that session_start_at is perceived as VARCHAR.
However, for the type of casting described as a solution to my issue to work, in the linked discussion, SELECT need to be used, it seems. Everything that I tried including string manipulations did not work.
How could I re-write my query/casts for Athena to process my request?
I ended up with:
CAST(DATE_PARSE(my_varchar_date, '%Y-%m-%dT%H:%i:%s.%f%z') AS TIMESTAMP)

How to run PostgreSQL Query every day with updated values?

New to SQL, but trying to learn/do a job for a friend. I have a query set up that returns the number of bookings for the day. Example snippet:
...
WHERE be.event IN ('instant_approve', 'approve') AND TO_CHAR(be.created_at, 'yyyy-mm-dd') BETWEEN '2017-06-26' AND '2017-06-26';
Now, this query is set up for just today. How can I set this up so that tomorrow the query is executed for '2017-06-27' and so on? Is this possible?
Built-in function now() gives you a timestamp of the beginning of your transaction (CURRENT_TIMESTAMP pseudo-constant is its "alias", a part of SQL standard, but I prefer using the function).
Another function, date_trunc() gives you a "truncated" timestamp and you can choose, how to truncate it. E.g., date_trunc('day', now()) will give you the date/time of beginning of the current day.
Also, you can add or subtract intervals easily, so here is an example that gives you the beginning of the current and the next days:
select
date_trunc('day', now()) cur_day_start,
date_trunc('day', now() + interval '1 day') as next_day_start
;
Also, I would not use to_char() or anything else on top of created_at column -- this will not allow Postgres planner use index on top of this field. If you do want to use to_char(), then consider adding a functional index over to_char(created_at, 'yyyy-mm-dd').
Here is how I would retrieve records generated at July 26, 2017:
where
created_at between '2017-06-26' and '2017-06-27'
(implicit type casting from text to timestamps here)
This is equivalent to
where
created_at >= '2017-06-26'
and created_at <= '2017-06-27'
-- so all timestamps generated for July 26, 2017 will match. And for such query Postgres will use a regular index created for created_at column (if any).
"Dynamic" version:
where
created_at between
date_trunc('day', now())
and date_trunc('day', now()) + interval '1 day'
Use current_date built-in function in the between condition and it will work only for today's bookings.
.........
WHERE be.event IN ('instant_approve', 'approve') AND TO_CHAR(be.created_at, 'yyyy-mm-dd') =current_date;

Filter Data for 30 months using subquery with INTERVAL function in Teradata

I would like to filter out the data using a sub query in the interval function
Following is the query i use
SEL * FROM my_table WHERE MY_DATE < CURRENT_DATE- INTERVAL '30' MONTH;
The above query works, However i want to parameterize the period '30' using a sub query. Please suggest how to achieve this.
Thanks in Advance
Don't use interval calculations with year/month as it will fail, e.g. DATE '2016-12-31' + INTERVAL '30' MONTH results in 2019-06-31 (according to Standard SQL) which obviously doesn't exist.
SELECT *
FROM my_table
WHERE MY_DATE < ADD_MONTHS(CURRENT_DATE, (SELECT -col FROM tab));
If col is actually an INTERVAL you need to cast it to an INT.

How to add variable minutes to a given date?

I have the next query (I'm using postgresql):
SELECT TIMESTAMP fecha_cita + cast((select tiempo_intervencion from cita_intervencion) as interval)
from cita;
What I'm doing here is basically taking a date like this '2001-09-28 01:00' from the 'cita' table (that's what fecha_cita is) and I want to add more time to this complete date, in this case 'tiempo_intervencion' is something like '120 minutes' but this information is in a different table called 'cita_intervencion', the problem is that since these are variables dates and times and not a fixed date, things like SELECT TIMESTAMP '2010-11-19 01:11:22' + INTERVAL '120 minutes doesn't work for me, I get errors like:
ERROR: syntax error at or near "fecha_cita"
LINE 1: SELECT TIMESTAMP fecha_cita + cast((select tiempo_intervenci...
ERROR: cannot cast type d_entero_p to interval
LINE 1: ...ct tiempo_intervencion from cita_intervencion) as interval) ...
I've looked up on google for some information on this and I was trying to follow this, but I can't find anything that can solve my problem.
You need a join and then cast the string to an interval:
SELECT c.fecha_cita, fecha_cita + ci.tiempo_intervencion::interval
from cita c
join cita_intervencion ci on c.id = ci.cita_id;
This assumes that there is some column in cita_intervencion that links that back to the cita table. If you really do not have that you can do something like this:
SELECT c.fecha_cita, fecha_cita + (select tiempo_intervencion::interval from cita_intervencion)
from cita c
But that will only work if cita_intervencion contains exactly one row.
The casting to an interval will only work if the values in tiempo_intervencion follow the rules for an interval.
You do not need the timestamp keyword for columns already defined as a timestamp that is only needed to introduce a timestamp literal (constant) value.
SELECT TIMESTAMP '2010-11-19 01:11:22' + INTERVAL '120 minutes doesn't work for me
That works if you add the missing ' for the interval literal:
SELECT TIMESTAMP '2010-11-19 01:11:22' + INTERVAL '120 minutes'
You can use:
select DATEADD(MINUTE,120,GETDATE())