How to subtract a number of days in one column from CURRENT_DATE in PostgreSQL - postgresql

I have a column called number_of_days_since_event and I want to change it to data_of_last_event, the way I can do that is subtracting today's date from the number of days in the number_of_days_since_event column. But I do not know how to subtract days in a column.
This question answers the problem when you know the number of days in advance, i.e., if I would like to subtract 10 days from today it would be:
SELECT CURRENT_DATE - INTERVAL '10 days';
However, I would like to do something like:
SELECT CURRENT_DATE - INTERVAL "myTable.number_of_days_since_event" 'days'
FROM myTable;
But this does not work leading to the error message: syntax error at or near "'day'"

The following using concat solves my problem:
SELECT CURRENT_DATE - concat(myTable.number_of_days_since_event::text,' day')::interval
FROM myTable;

If you are happy with a date result, you could use
SELECT current_date - number_of_days_since_event::integer
FROM mytable;

Related

PostgreSQL: Syntax error at or near "14" when trying to run a delete query

First question here!
So I have a table with a row like this:
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
I would like to run a query that delete all the data in my table older than 14 days.
This is my query:
DELETE FROM customers WHERE timestamp < NOW() - INTERVAL 14 DAY;
This is the error: syntax error at or near "14"
Anyone knows why this is not working and/or how could I achieve my goal??
Many thanks!!
The interval value must be quoted:
DELETE FROM customers WHERE created_at < NOW() - INTERVAL '14 DAYS';
See the doc
DELETE FROM customers WHERE created_at < NOW() - INTERVAL '14 DAY';
Another variation on the existing answers (possibly easier to remember):
DELETE FROM customers WHERE timestamp < NOW() - '14 days'::interval;

How to get the values from dummy table to variables?

(SELECT SUBSTRING(TO_CHAR(current_timestamp, 'yyyy-mm-dd hh12:mi:ss AM'),21,2)),
current_date ,
current_date - INTERVAL '1' DAYS,
to_char(current_date,'Day') into
vs_current_ampm,
vd_current_dt,
vd_prev_dt,
vl_day;
The forementioned query has a minor syntax error, i.e., an extra ) after 21,2.
I have changed that and the below query works fine.
SELECT
SUBSTRING(TO_CHAR(current_timestamp, 'yyyy-mm-dd hh12:mi:ss AM'),21,2),
current_date , current_date - INTERVAL '1' DAYS,
to_char(current_date,'Day');
If you would like to use the results in another place, you might need to use a cursor as I mentioned in the comments.
Check the documentation here.

Subtract month from date column

I would like to subtract one month from a date column in Amazon Redshift (a fork of PostgreSQL 8.0.2).
So for each date column in a table, it will add another column date_minus_a_month.
I tried this code
Select date,date::date -interval '1 month'
from table
and received an error:
Interval values with month or year parts are not supported.
Does anyone have a solution for this?
You can use datesub, although I just use dateadd for everything and use negative numbers.
eg
SELECT getdate() as right_now, dateadd(month, -1, getdate()) as last_month
Docs: https://docs.aws.amazon.com/redshift/latest/dg/r_DATEADD_function.html

How can I get a floating average over timestamps in PostgreSQL?

Let's say I have a table for a time-sheet like this:
CREATE TABLE foo (
spent_on DATETIME,
hours FLOAT
)
Assuming spent_on is the timestamp the value was logged, and hours is a floating point value representing the amount of hours spent on a task.
How can I get a floating average of hours over the past 7 days?
I've came up with the following but it won't work:
select spent_on, hours, avg(hours)
over RANGE BETWEEN spent_on - INTERVAL '7 days' AND CURRENT ROW from daily;
I get the following error:
ERROR: syntax error at or near "ROW"
LINE 1: ... BETWEEN spent_on - INTERVAL '7 days' AND CURRENT ROW from d...
I've tried to understand the docs for window functions, but I have real trouble grasping the idea between partitions, windows and frames. And as a result, can't come up with a query.
I'm not sure about the RANGE syntax, so let me offer a solution with a sub query (If performance is not an issue with small tables ETC..) :
SELECT t.spent_on,t.hours,
COALESCE( (SELECT AVG(s.hours) FROM foo
WHERE t.spent_on > CURRENT_TIMESTAMP - INTERVAL '7 days'),0) float_avg
FROM foo t

PostgreSQL: exists robust third party date-math functions to augment the built-in date operators?

I'm porting some T-SQL stored procs to PL/pgSql and, being very new to PostgreSQL, don't know what helpful utility functions might be available in the pg community. Is there a set of robust date-math functions that "nearly everybody uses" out there somewhere? I don't want to quickly cobble together some date-math functions if there's already a great package out there.
The PostgreSQL date math operators with "natural language" string literal arguments are user-friendly if you're typing a query and you happen to know the interval:
select now() - interval '1 day'
but if the interval 1 is the result of a calculation involving nested date-math function calls, these string literals are actually not very user-friendly at all, and it would easier to work with a date_add function:
select dateadd(d, {calculation that returns the interval}, now() )
Thanks
Let me give you an example. I want to subtract from an arbitrary date the number of months that have elapsed since 1/1/1970, and then add that number of months to 1/1/1970 to return the first day of the month in which the arbitrary date falls
select (date_trunc('month', '2013-01-30'::date))::date
Or add a month to the first day of this month to get the first day of the next month, then subtract one day to get the last day of this month
select date_trunc('month', '2013-01-30'::date + 1 * interval '1 month')::date - 1
Notice in the above example you can add any number of months by multiplying the interval '1 month' by an integer. You can do that with any interval without manipulating the string '1 month'. So to add or subtract any interval you just:
select current_date + 5 * interval '1 month'
No need for messy string manipulations. You can multiply by fractions also:
select current_timestamp + 3.5 * interval '1 minute'
To add or subtract days to a date type you use an integer:
select current_date + 10
The "natural language" strings you're talking about are interval literals. Intervals can also be obtained by using date arithmetic.
Surely dateadd can be quite simply emulated in Postgresql as follows:
select d + ({calculation the returns the interval}::text || ' day')::interval
Substitute "month" or "hours" etc as appropriate.
In PostgreSQL, you simply add and subtract interval values to datetime
values:
'2001-06-27 14:43:21'::TIMESTAMP - '00:10:00'::INTERVAL = '2001-06-27 14:33:21'::TIMESTAMP
'2001-06-27 14:43:21'::TIMESTAMP- '2001-06-27 14:33:21'::TIMESTAMP = '00:10:00'::INTERVAL
For more information, see "Functions and Operators" in the PostgreSQL
online docs.
To compute the first day of the month of a date: date_trunc('month', date)
First day of the next month: date_trunc('month', date) + '1 month'::INTERVAL
Add three months to the first day of the month of this date: date_trunc('month', date) + 3*('1 month'::INTERVAL)
The interval is a data type, not a string, and you can do computations with its values.