trunc(add_months(sysdate,3),'Q')-1 equivalent expression in Postgres - sql

can anybody convert this oracle expression trunc(add_months(sysdate,3),'Q')-1) to postgresql?

Basically this expression gives you the last day of the current quarter (provided that you remove the last closing parenthese, which otherwise is a syntax error).
In postgres, you could phrase this as:
date_trunc('quarter', current_date) + interval '3 months' - interval '1 day'
This generates a timestamp value, that you can cast if you want a date (this distinction does not exist in Oracle, where a date stores the time component as well).

The Postgres equivalent of your Oracle calculation can be seen below.
select date_trunc('quarter', current_date + interval '3 month') - interval '1 day'

Related

Incrementing Date - SQL(Snowflake)

I want to Increment/Decrement the Year , Day , Month by pulling in the Current Date in Snowflake in a single query ?
For e.g.
Suppose Current System Date - 04082021 I want to make it 05092022. I have tried the dateadd function but I suppose it allows only one part i.e. either year or month or day to be incremented at once.
Is it Possible ? If Not, What are the other alternatives ?
If you want to useDATEADD function, here is the code:
SELECT DATEADD(YEAR,+1,DATEADD(MONTH,+1,DATEADD(DAY,+1,CURRENT_DATE())));
returns 2022-09-05 from 2021-08-04
If you want to keep your format, Please use following code
SELECT TO_CHAR(DATEADD(YEAR,+1,DATEADD(MONTH,+1,DATEADD(DAY,+1,CURRENT_DATE()))),'DDMMYYYY');
I would do the arithmetic in thee parts:
select current_date + interval '1 year' + interval '1 month' + interval '1 day'
You can also use:
select current_date + interval '1 year, 1 month, 1 day'

Different query results while using DATE_TRUNC function in WHERE clause

I have a SQL query which gives different set of result when I use condition
DATE_TRUNC('DAY', timestamp) BETWEEN date_trunc('DAY', NOW()) - interval '14' day AND date_trunc('DAY', NOW())
and a different result when I use condition
timestamp BETWEEN date_trunc('DAY', NOW()) - interval '14' day AND date_trunc('DAY', NOW())
After cross checking both the query results I found that first condition is giving correct result.
Can someone please tell me the difference between both the conditions.
Thanks in advance
timestamp has a time component.
date_trunc(day, timestamp) removes the time component.
The second part of the comparison is different. The first version returns any time on the current day.
The second version only returns midnight on the current day.
Incidentally, I would recommend:
where timestamp >= current_date - interval '14 day' and
timestamp < current_date + interval '1 day'
This works, regardless of whether the timestamp column has a time component or not. And, it is friendly to the optimizer and index usage.

Not abe to declare as timestamp in postgreSQL

select *
From #####
where username in ('akhil') and between (now() ::timestamp and now() - interval '1 day'::timestamp)
Getting error in this line .
Error - cannot cast type interval to timestamp without time zone .
You don't need the second cast. You need a column name. Something like this:
select *
from #####
where username in ('akhil') and
<some date column> >= now() - interval '1 day' and
<some date column> < now();
the error is in the second cast
now() - interval '1 day'::timestamp
is interprested as.
now() - (interval '1 day')::timestamp
when you actually mean
(now() - interval '1 day')::timestamp
or possibly you mean
now()::timestamp - interval '1 day'
both are valid, but the the result you'll get when daylight saving starts or stops is different (hint interval '1 day' is the same as interval '24 hours' in the first)
There's a strong possiblity that you should actually be using timestamp with time zone for the database column.

How to get the last day of month in postgres?

How to find the last day os the month in postgres?
I have a date columns stored as numeric(18) in the format(YYYYMMDD)
I am trying it to make it date using
to_date("act_dt",'YYYYMMDD') AS "act date"
then find the last day of this date:
like this:
(select (date_trunc('MONTH',to_date("act_dt",'YYYYMMDD')) + INTERVAL '1 MONTH - 1 day')::date)
but it gives me this error:
ERROR: Interval values with month or year parts are not supported
Detail:
-----------------------------------------------
error: Interval values with month or year parts are not supported
code: 8001
context: interval months: "1"
query: 673376
location: cg_constmanager.cpp:145
process: padbmaster [pid=20937]
-----------------------------------------------
Any help?
Postgres version:
PostgreSQL 8.0.2 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3), Redshift 1.0.874
For anybody coming to this question looking for the Postgres way to do this (not using Redshift), here's how you'd do it:
SELECT (date_trunc('month', '2017-01-05'::date) + interval '1 month' - interval '1 day')::date
AS end_of_month;
Replacing the '2017-01-05' with whatever date you want to use. You can make this into a function like this:
create function end_of_month(date)
returns date as
$$
select (date_trunc('month', $1) + interval '1 month' - interval '1 day')::date;
$$ language 'sql'
immutable strict;
EDIT Postgres 11+
Pulling this out of the comments from #Gabriel, you can now combine interval expressions in one interval (which makes things a little shorter):
select (date_trunc('month', now()) + interval '1 month - 1 day')::date as end_of_month;
-- +--------------+
-- | end_of_month |
-- +--------------+
-- | 2021-11-30 |
-- +--------------+
-- (1 row)
If you're using Amazon AWS Redshift then you can use Redshift's LAST_DAY function. While Redshift is based on PostgreSQL, the LAST_DAY function is not available in PostgreSQL, for a solution for PostgreSQL see #wspurgin's answer.
https://docs.aws.amazon.com/redshift/latest/dg/r_LAST_DAY.html
LAST_DAY( { date | timestamp } )
LAST_DAY returns the date of the last day of the month that contains date. The return type is always DATE, regardless of the data type of the date argument.
For example:
SELECT LAST_DAY( TO_DATE( act_date, 'YYYYMMDD' ) )
Okay, so you've got a numeric(18) column containing numbers like 20150118. You can convert that to a date like:
to_date(your_date_column::text, 'YYYYMMDD')
From a date, you can grab the last day of the month like:
(date_trunc('month', your_date_column) +
interval '1 month' - interval '1 day')::date;
Combined, you'd get:
select (date_trunc('month', to_date(act_dt::text, 'YYYYMMDD')) +
interval '1 month' - interval '1 day')::date
from YourTable;
Example at SQL Fiddle.
date_trunc('month',current_date) + interval '1 month' - interval '1 day'
Truncating any date or timestamp to the month level will give you the first of the month containing that date. Adding a month gives you the first of the following month. Then, removing a day will give you the date of the last day of the month of the provided date.
For future searches, Redshift does not accept INTERVAL '1 month'. Instead use dateadd(month, 1, date) as documented here.
To get the end of the month use: DATEADD(DAY, -1, (DATE_TRUNC('month', DATEADD(MONTH, 1, date))))
select to_char(date_trunc('month', now() + '01 Months'::interval) - '01 Days'::interval, 'YYYYmmDD'::text)::numeric as end_period_n

How to list records with date from the last 10 days?

SELECT Table.date FROM Table WHERE date > current_date - 10;
Does this work on PostgreSQL?
Yes this does work in PostgreSQL (assuming the column "date" is of datatype date)
Why don't you just try it?
The standard ANSI SQL format would be:
SELECT Table.date
FROM Table
WHERE date > current_date - interval '10' day;
I prefer that format as it makes things easier to read (but it is the same as current_date - 10).
http://www.postgresql.org/docs/current/static/functions-datetime.html shows operators you can use for working with dates and times (and intervals).
So you want
SELECT "date"
FROM "Table"
WHERE "date" > (CURRENT_DATE - INTERVAL '10 days');
The operators/functions above are documented in detail:
CURRENT_DATE
INTERVAL '10 days'
My understanding from my testing (and the PostgreSQL dox) is that the quotes need to be done differently from the other answers, and should also include "day" like this:
SELECT Table.date
FROM Table
WHERE date > current_date - interval '10 day';
Demonstrated here (you should be able to run this on any Postgres db):
SELECT DISTINCT current_date,
current_date - interval '10' day,
current_date - interval '10 days'
FROM pg_language;
Result:
2013-03-01 2013-03-01 00:00:00 2013-02-19 00:00:00
The suggested answers already seem to solve the questions. But as an addition I am suggesting to use the NOW() function of PostgreSQL.
SELECT Table.date
FROM Table
WHERE date > now() - interval '10' day;
Additionally you can even specifiy the time zone which can be really handy.
NOW () AT TIME ZONE 'Europe/Paris'
Starting with Postgres 9.4 you can use the AGE function:
SELECT Table.date FROM Table WHERE AGE(Table.date) <= INTERVAL '10 day';
Just generalising the query if you want to work with any given date instead of current date:
SELECT Table.date
FROM Table
WHERE Table.date > '2020-01-01'::date - interval '10 day'
I would check datatypes.
current_date has "date" datatype, 10 is a number, and Table.date - you need to look at your table.
you can use between too:
SELECT Table.date
FROM Table
WHERE date between current_date and current_date - interval '10 day';