Explain Codes LogoExplain Codes Logo

How to extract year and month from date in PostgreSQL without using to_char() function?

sql
date_trunc
extract
date_part
Nikita BarsukovbyNikita Barsukov·Nov 11, 2024
TLDR

EXTRACT() is your go-to function when you need to isolate the year and month from a date field in PostgreSQL:

SELECT EXTRACT(YEAR FROM date_column) AS year, EXTRACT(MONTH FROM date_column) AS month FROM table_name;

This command fetches the numeric year and month, avoiding any formatting gymnastics.

Swapping techniques: Utilizing date_trunc()

While EXTRACT() nails the task, PostgreSQL's date_trunc function provides an alternative. It truncates the date to your desired precision, allowing you to zero in on a specific part of the date:

SELECT date_trunc('month', date_column)::date AS first_day_of_month FROM table_name; -- This is truncating the day as if it overslept and missed its alarm. Oops!

In case you need a "YYYY-MM" format, you can combine extract and LPAD():

SELECT extract(year FROM date_column)::text || '-' || LPAD(extract(month FROM date_column)::text, 2, '0') AS year_month FROM table_name; -- It's like creating a secret numeric date language. Shh, don't tell anyone!

Here, LPAD() ensures that the month is always represented with two digits.

Proper chronological ordering

When ordering your data, particularly if you're grouping it by year and month, it's important to retain proper chronological ordering. date_trunc is valuable in this situation as it preserves the date part:

SELECT date_trunc('month', date_column) AS month_start, COUNT(*) FROM table_name GROUP BY month_start ORDER BY month_start; -- Trying to organize your data as a date party and making sure no one crashes it!

Ensure your ORDER BY clause aligns with your truncation or extraction method to avoid the messy party of mixed-up dates.

Doing more with date_part

date_part is another PostgreSQL function offering precision with more flexibility:

SELECT date_part('year', date_column) AS year, date_part('month', date_column) AS month FROM table_name; -- It's like playing with Lego but with date parts!

Although date_part is identical to EXTRACT() in many ways, date_part is more accommodating with time zones and intervals, making it your best ally in more complex scenarios.

Mastering advanced date operations

From month start with date_trunc()

Grouping transactions by the month they occurred becomes a piece of cake with date_trunc():

SELECT date_trunc('month', date_column)::date AS month_start FROM table_name; -- It's like getting a calendar, but only the first day of each month is marked!

Getting year start with date_trunc()

Need the starting date of the year? Here's how:

SELECT date_trunc('year', date_column)::date AS year_start FROM table_name; -- It's like celebrating New Year's Day, but every day!

This method neatly aligns transactions with their fiscal years.

Handling intervals like a boss

Cool operators in PostgreSQL allow handy comparisons for ranges or intervals:

SELECT CASE WHEN (current_date - date_column) < INTERVAL '1 year' THEN 'Newer than a year' ELSE 'Older than a year' END AS time_comparison FROM table_name; -- It's like comparing two siblings; "Who's older? Let's find out!"

Gleaning insights without formatting

Sometimes your focus is on insights rather than formatting, particularly for data analysis:

SELECT EXTRACT(YEAR FROM date_column) AS year, COUNT(*) AS count FROM table_name GROUP BY year ORDER BY year; -- We're creating a yearbook here; nostalgia, anyone?

This command swiftly gets a count of records for each year, perfect for an analytical overview.