PostgreSQL: Select rows between two dates/timestamps

Updated: January 5, 2024 By: Guest Contributor Post a comment

Introduction

Working with dates is a common task in database management. In PostgreSQL, querying rows between two specific dates or timestamps can be accomplished with straightforward SQL queries. This tutorial will guide you through multiple examples, from basic methods to more advanced scenarios.

Getting Started

To select rows within a date range, you’ll typically use the BETWEEN operator in PostgreSQL. This operator selects values within a given range. The values can be numbers, text, or dates. A basic query to find rows between two dates looks like this:

SELECT *
FROM your_table
WHERE your_date_column BETWEEN '2023-01-01' AND '2023-01-31';

It’s crucial to ensure that your dates are formatted in a way that PostgreSQL understands, generally in the format YYYY-MM-DD or YYYY-MM-DD HH:MI:SS.

Using BETWEEN with Timestamps

When working with timestamps, you can still use the BETWEEN operator, but you should include time information to be as precise as possible:

SELECT *
FROM your_table
WHERE your_timestamp_column BETWEEN '2023-01-01 00:00:00' AND '2023-01-31 23:59:59';

This ensures you capture all records up until the very last second of the end date.

Time Zones and Timestamps with Time Zone

PostgreSQL also supports timestamps with time zones. You should consider time zone differences when querying your data. To convert a timestamp with a time zone to a specific time zone, you can use the AT TIME ZONE clause:

SELECT *
FROM your_table
WHERE your_timestamptz_column AT TIME ZONE 'UTC' BETWEEN '2023-01-01 00:00:00+00' AND '2023-01-31 23:59:59+00';

Note that when interpreting text as timestamp with time zone, PostgreSQL assumes that the text represents a time in your current time zone unless a different zone is specified.

Advanced Queries: Functions and Indexes

If you need to query a part of a date, such as retrieving all rows from a particular month regardless of the year, you can use PostgreSQL functions. Here’s an example query that selects rows from June:

SELECT *
FROM your_table
WHERE EXTRACT(MONTH FROM your_date_column) = 6;

In some cases, you may be dealing with large sets of data and performance can become an issue. Indexing your date columns can help improve the performance of your queries. A standard B-tree index is adequate for most scenarios:

CREATE INDEX idx_your_date_column
ON your_table (your_date_column);

If you frequently run range queries on a date column, you may benefit from a BRIN (Block Range Index) as it’s suitable for large tables with naturally ordered data.

Handling NULL Values and Filtering

Some rows in your database might have NULL values for the date column. If you need to exclude these from your results, make sure to add a condition that filters them out:

SELECT *
FROM your_table
WHERE your_date_column IS NOT NULL AND your_date_column BETWEEN '2023-01-01' AND '2023-01-31';

This will prevent NULL values from appearing in your result set, which might otherwise cause confusion or errors in your application.

Combining Date Queries with Other Conditions

Often, you’ll need to combine date range queries with other filtering conditions to refine your results. Here’s how you can filter based on both a date range and another column value:

SELECT *
FROM your_table
WHERE your_date_column BETWEEN '2023-01-01' AND '2023-01-31'
AND your_other_column = 'Some Value';

It’s important to use your WHERE clauses wisely to optimize performance, especially when dealing with large datasets.

Conclusion

Selecting rows between two dates or timestamps in PostgreSQL is a fundamental skill that can be mastered with a bit of practice. Starting with basic BETWEEN queries, we’ve explored more advanced techniques, included handling different time zones, and considered performance aspects such as indexing. Understanding these concepts and methods will enhance your ability to manage and analyze time-based data efficiently.