date_part with composite fields in PostgreSQL - sql

Is it possible to use the date_part function to extract a composite of multiple specifiers?
For example, I'd like to extract the month, day of month, and hour of day from a timestamp in the single string form "month:day-of-month:hour-of-day" so that
`SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');`
would return "02:16:20"

This is much easier with to_char():
select to_char(TIMESTAMP '2001-02-16 20:38:40', 'MM:DD:HH24')
The documentation describes the formatting options.

Related

When to use DATE_TRUNC() vs. DATE_PART()?

I do not know when to use DATE_TRUNC and DATE_PART() in a query.
I have not really tried much, just some web searches that I do not fully grasp but I just started learning SQL (Postgres).
They both do very different things. One truncates a date to the precision specified (kind of like rounding, in a way) and the other just returns a particular part of a datetime.
From the documentation:
date_part():
The date_part function is modeled on the traditional Ingres equivalent
to the SQL-standard function extract:
date_part('field', source)
Note that here the field parameter needs to be a string value, not a
name. The valid field names for date_part are the same as for extract.
For historical reasons, the date_part function returns values of type
double precision. This can result in a loss of precision in certain
uses. Using extract is recommended instead.
SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
Result: 16
SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
Result: 4
date_trunct():
The function date_trunc is conceptually similar to the trunc function
for numbers.
date_trunc(field, source [, time_zone ]) source is a value expression
of type timestamp, timestamp with time zone, or interval. (Values of
type date and time are cast automatically to timestamp or interval,
respectively.) field selects to which precision to truncate the input
value. The return value is likewise of type timestamp, timestamp with
time zone, or interval, and it has all fields that are less
significant than the selected one set to zero (or one, for day and
month).
...
Examples (assuming the local time zone is America/New_York):
SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-02-16 20:00:00
SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-01-01 00:00:00
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
Result: 2001-02-16 00:00:00-05
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney');
Result: 2001-02-16 08:00:00-05
SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
Result: 3 days 02:00:00

Format of Date_Trunc in SQL (Redshift)

The below works:
SELECT DATE_TRUNC('day', TIMESTAMP '2017-03-17 02:09:30')
But if I remove the "TIMESTAMP" part (as below) it doesn't. Why is this?
SELECT DATE_TRUNC('day', '2017-03-17 02:09:30')
From what I understand, the format should just be:
DATE_TRUNC('datepart', timestamp)
This simple format works in other situations..
The timestamp '2017-03-17' is a so-called timestamp-literal. The prefix timestamp is what makes this a timestamp and not a char. If you just have '2017-03-17', then it is a char-literal, which is not a timestamp, and DATE_TRUNC requires a datetime value.
Try this
select date_trunc('week', to_date('28/10/2020','dd/mm/yyyy'))
It will return date of monday for current week.

Postgres: How do I extract year and month from a date?

One of my columns is a date type in the following format: YYYY-MM-DD. I want to extract YYYY-MM. So far, the resources I've come across show me that I can extract either year using SELECT extract(year from order_date)... but I can't figure out how to extract both the year and the month. I tried the following but it didn't work: https://www.w3schools.com/sql/func_mysql_extract.asp
I just want to point out that it is often convenient to leave the value as a date. If so, use date_trunc():
select date_trunc('month', order_date) as yyyymm
If you really want a string, you should accept Nick's answer.
In PostgreSQL you can use TO_CHAR():
SELECT TO_CHAR(order_date, 'YYYY-MM')
Output (if order_date = '2020-04-06'):
2020-04
Note if your column is not already a date or timestamp you will need to cast it to a date or timestamp (e.g. order_date::date).
Demo on dbfiddle

Date_Trunc not function working as expected

I am trying to use the Date_Trunc for MONTH function in a SQL statement but somehow it is not working for me. I am trying to pull entries which happen after April 1st, 2019. The raw date format from the Redshift database is this format which I am trying to group into month/year buckets: 2019-04-08T00:13:20.000Z
Input
SELECT
client_id as user_id,
session_utc as job_date --(format:2019-04-08T00:13:20.000Z)
FROM table1 as hits
WHERE job_date >= DATE_TRUNC('month', 2019-04-01)
group by 1,2;
Output
"ERROR: function date_trunc("unknown", integer) does not exist Hint: No function matches the given name and argument types. You may need to add explicit type casts."
What am I doing wrong?
The DATE_TRUNC Function - Amazon Redshift takes timestamp as input and provides a timestamp as output:
DATE_TRUNC('datepart', timestamp)
For example:
SELECT DATE_TRUNC('month', '2019-05-07'::timestamp)
2019-05-01 00:00:00
Therefore, your line should read:
WHERE job_date >= DATE_TRUNC('month', '2019-04-01'::timestamp)
If you wish to have the output as a date, append ::date:
SELECT DATE_TRUNC('month', '2019-05-07'::timestamp)::date
2019-05-01
Also, note that the date converts into a timestamp as at midnight. This can cause a difference for some comparisons. For example:
'2019-05-07 03:03:31.389324+00'::timestamp > '2019-05-07'::timestamp
will evaluate as True because it is comparing to midnight at the start of the day. This is different to comparing two dates (without timestamps).
The syntax for the function is DATE_TRUNC('datepart', timestamp), seems you need to use as DATE_TRUNC('month', session_utc)(this already truncates to the first date of April 2019 i.e. 2019-04-01 )
Assuming you are using Postgres, you need quotes around your date constant and can convert to the right types:
WHERE job_date >= DATE_TRUNC('month'::text, '2019-04-01'::date)
Here is a db<>fiddle.

Filter timestamp by specific month-year

I am new to postgres and would appreciate any advice. I have postgres table with a timestamp column whose values are in the format: 1970-01-01 00:00:00
My objective is to select records from the last three whole months - December 2016, January 2017 and February 2017. How would one write this query with only read access using SELECT?
When I start with:
SELECT to_char("start_time", 'YYYY-MM-DD HH:MM:SS') FROM trips;
Times are converted to AM/PM but I am only interested in extracting and subsetting by month and year
Here you go:
SELECT *
FROM trips
WHERE start_time BETWEEN '2016-01-01 00:00:00'::timestamp AND '2017-02-28 23:59:59'::timestamp;
You can use extract or date_trunc function to extract month in postgresql.
Very similar to question get last three month records from table
For more details about date time functions in postgresql use below link.
https://www.postgresql.org/docs/9.1/static/functions-datetime.html
Here is one method:
select t.*
from t
where start_date >= date_trunc('month',now() - interval '3' month) and
start_date < date_trunc('month', now());