---
title: Postgres Boolean data type
subtitle: Represent truth values in Postgres
enableTableOfContents: true
updatedOn: '2024-06-14T07:55:54.365Z'
---
In Postgres, the Boolean datatype is designed to store truth values. A Boolean column can hold one of three states: `true`, `false`, or `NULL` representing unknown or missing values.
For instance, Boolean values can be used in a dataset to represent the status of an order, whether a user is active, or whether a product is in stock. A Boolean value could also be produced as a result of comparisons or logical operations.
## Storage and syntax
In SQL statements, Boolean values are represented by the keywords `TRUE`, `FALSE`, and `NULL`. Postgres is flexible and allows for various textual representations of these values:
- `TRUE` can also be represented as `t`, `true`, `y`, `yes`, `on`, `1`.
- `FALSE` can also be represented as `f`, `false`, `n`, `no`, `off`, `0`.
A boolean value is stored as a single byte.
## Example usage
Consider a table of users for a web application. We can add a Boolean column to represent whether a user is active or not.
The query below creates a `users` table and inserts some sample data:
```sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
is_active BOOLEAN,
has_paid_subscription BOOLEAN
);
INSERT INTO users (username, is_active, has_paid_subscription)
VALUES
('alice', TRUE, TRUE),
('bob', TRUE, FALSE),
('charlie', FALSE, TRUE),
('david', NULL, NULL),
('eve', FALSE, FALSE);
```
Say we want to find all the users currently active on the website. The `WHERE` clause accepts a Boolean expression, so we can filter down to the rows where the `is_active` column is `TRUE`.
```sql
SELECT *
FROM users
WHERE is_active = TRUE;
```
This query returns the following:
```text
| id | username | is_active | has_paid_subscription |
|----|----------|-----------|-----------------------|
| 1 | alice | t | t |
| 2 | bob | t | f |
```
## Other examples
### Conditional logic
Boolean data types are commonly used in conditional statements like `WHERE`, `IF`, and `CASE`. For example, the `CASE` statement is a control flow structure that allows you to perform `IF-THEN-ELSE` logic in SQL.
In the query below, we categorize users based on their activity and account type.
```sql
SELECT username,
CASE
WHEN is_active = TRUE AND has_paid_subscription = TRUE THEN 'Active Paid'
WHEN is_active = TRUE AND has_paid_subscription = FALSE THEN 'Active Free'
WHEN is_active = FALSE AND has_paid_subscription = TRUE THEN 'Inactive Paid'
WHEN is_active = FALSE AND has_paid_subscription = FALSE THEN 'Inactive Free'
ELSE 'Unknown'
END AS user_status
FROM users;
```
This query returns the following:
```text
| username | user_status |
|----------|---------------|
| alice | Active Paid |
| bob | Active Free |
| charlie | Inactive Paid |
| david | Unknown |
| eve | Inactive Free |
```
### Boolean expressions
Boolean expressions combine multiple boolean values using operators like `AND`, `OR`, and `NOT`. These expressions return boolean values and are crucial in complex SQL queries.
For example, we can use a Boolean expression to find all the users who are active but don't have a paid subscription yet.
```sql
SELECT id, username
FROM users
WHERE is_active = TRUE AND has_paid_subscription = FALSE;
```
This query returns the following:
```text
| id | username |
|----|----------|
| 2 | bob |
```
### Boolean aggregations
Postgres also supports aggregating over a set of Boolean values, using functions like `bool_and()` and `bool_or()`.
For example, we can query to check that no inactive users have a paid subscription.
```sql
SELECT bool_or(has_paid_subscription) AS inactive_paid_users
FROM users
WHERE is_active = FALSE;
```
This query returns the following:
```text
| inactive_paid_users |
|---------------------|
| t |
```
This indicates there is at least one inactive user with an ongoing subscription. We should probably email them a reminder to log in.
### Boolean in join conditions
Booleans can be effectively used in the `JOIN` clause to match rows across tables.
In the query below, we join the `users` table with the table containing contact information to send a promotional email to all active users.
```sql
WITH contacts (user_id, email) AS (
VALUES
(1, 'alice@email.com'),
(2, 'bob@email.com'),
(3, 'charlie@email.com'),
(4, 'david@email.com'),
(5, 'eve@email.com')
)
SELECT u.id, u.username, c.email
FROM users u
JOIN contacts c ON u.id = c.user_id AND u.is_active = TRUE;
```
This query returns the following:
```text
| id | username | email |
|----|----------|-----------------|
| 1 | alice | alice@email.com |
| 2 | bob | bob@email.com |
```
## Additional considerations
- **NULL**: `NULL` in boolean terms indicates an unknown state, which is neither `TRUE` nor `FALSE`. In conditional statements, `NULL` values will not equate to `FALSE`.
- **Type Casting**: Be mindful when converting Booleans to other data types. For instance, casting a Boolean to an integer results in `1` for `TRUE` and `0` for `FALSE`. This behavior is useful in aggregations or mathematical operations.
- **Indexing**: Using Booleans in indexing might not always be efficient, especially if the distribution of true and false values is uneven.
## Resources
- [PostgreSQL Boolean Type documentation](https://www.postgresql.org/docs/current/datatype-boolean.html)