cyberangles guide

A Beginner’s Guide to PostgreSQL’s Built-In Functions and Operators

PostgreSQL, often called “Postgres,” is a powerful, open-source relational database management system (RDBMS) known for its robustness, flexibility, and extensive feature set. One of its most valuable strengths is its rich library of built-in functions and operators, which simplify common data manipulation, analysis, and transformation tasks. For beginners, mastering these tools is a foundational step toward writing efficient, clean, and effective SQL queries. Whether you’re calculating sums, formatting dates, cleaning text data, or handling null values, PostgreSQL’s built-in functions and operators eliminate the need for writing complex custom logic from scratch. This guide will break down the essentials—starting with basic operators, moving to core functions, and even touching on advanced topics—all with practical examples to help you apply what you learn.

Table of Contents

  1. What Are Functions and Operators?
  2. Core Operators in PostgreSQL
  3. Essential Built-In Functions
  4. Advanced Functions
  5. Practical Examples: Putting It All Together
  6. Best Practices for Using Functions and Operators
  7. Conclusion
  8. References

What Are Functions and Operators?

Before diving in, let’s clarify the basics:

  • Operators are symbols or keywords that perform operations on one or more values (operands). For example, + (addition) or = (equality check).
  • Functions are reusable blocks of code that take input (arguments) and return a value. They are called by name, e.g., SUM(amount) or UPPER(name).

PostgreSQL provides hundreds of operators and functions tailored to different data types (numbers, strings, dates, JSON, arrays, etc.). They are optimized for performance, so using them often leads to faster queries than writing custom logic.

Core Operators in PostgreSQL

Operators are the building blocks of SQL queries. Let’s explore the most common types:

Arithmetic Operators

Used to perform mathematical calculations on numeric values (integers, decimals, etc.).

OperatorDescriptionExampleResult
+Addition5 + 38
-Subtraction10 - 46
*Multiplication6 * 742
/Division20 / 45
%Modulus (remainder)15 % 43
^Exponentiation2 ^ 38

Example with a table: Suppose we have a sales table with a column amount (sale value). To calculate the total after a 10% tax:

SELECT amount, amount * 1.1 AS total_with_tax  
FROM sales;  

Comparison Operators

Used to compare values and return TRUE, FALSE, or NULL (if one operand is NULL).

OperatorDescriptionExample
=Equal toamount = 100
!=/<>Not equal toproduct != 'Laptop'
<Less thansale_date < '2023-01-01'
>Greater thanamount > 500
<=Less than or equal toquantity <= 10
>=Greater than or equal torating >= 4.5
BETWEENBetween two values (inclusive)amount BETWEEN 100 AND 500
INMatches any value in a listproduct IN ('Laptop', 'Phone')
LIKEPattern match (case-insensitive by default)customer_name LIKE 'A%' (names starting with “A”)
ILIKECase-insensitive pattern match (PostgreSQL-specific)product ILIKE 'laptop'

Example: Find sales of laptops or phones with amounts between $100 and $500:

SELECT *  
FROM sales  
WHERE product IN ('Laptop', 'Phone')  
  AND amount BETWEEN 100 AND 500;  

Logical Operators

Combine multiple conditions in WHERE clauses.

OperatorDescriptionExample
ANDBoth conditions must be trueamount > 100 AND product = 'Laptop'
ORAt least one condition is trueproduct = 'Laptop' OR product = 'Phone'
NOTNegates a conditionNOT (amount < 100) (amount ≥ 100)

Example: Find sales where the product is a laptop and the amount is over $500, or the product is a phone with a rating ≥ 4.5:

SELECT *  
FROM sales  
WHERE (product = 'Laptop' AND amount > 500)  
   OR (product = 'Phone' AND rating >= 4.5);  

String Operators

Used to manipulate text data.

OperatorDescriptionExampleResult
``Concatenation
~Regex match (case-sensitive)'PostgreSQL' ~ 'sql'FALSE (no match)
~*Regex match (case-insensitive)'PostgreSQL' ~* 'sql'TRUE (matches “SQL”)

Example: Combine first and last names into a full name:

SELECT first_name || ' ' || last_name AS full_name  
FROM customers;  

Date/Time Operators

PostgreSQL has special operators for dates, times, and intervals (durations).

OperatorDescriptionExampleResult
+Add interval to date/time'2023-10-01'::DATE + INTERVAL '7 days'2023-10-08 (1 week later)
-Subtract interval from date/timeNOW() - INTERVAL '1 month'Current time minus 1 month
-Calculate difference between dates'2023-12-31'::DATE - '2023-01-01'::DATE364 (days between dates)

Example: Find sales from the last 30 days:

SELECT *  
FROM sales  
WHERE sale_date >= NOW() - INTERVAL '30 days';  

Essential Built-In Functions

Functions extend PostgreSQL’s capabilities beyond basic operators. Let’s explore the most useful ones for beginners.

String Functions

Clean, format, or extract information from text data.

FunctionDescriptionExampleResult
LENGTH(text)Returns length of a string (in characters)LENGTH('PostgreSQL')10
UPPER(text)Converts text to uppercaseUPPER('hello')'HELLO'
LOWER(text)Converts text to lowercaseLOWER('WORLD')'world'
TRIM(text)Removes leading/trailing whitespaceTRIM(' excess space ')'excess space'
SUBSTRING(text FROM start FOR length)Extracts a substringSUBSTRING('PostgreSQL' FROM 1 FOR 4)'Post'
REPLACE(text, old, new)Replaces all occurrences of old with newREPLACE('hello', 'l', 'x')'hexxo'

Example: Clean and standardize product names (trim spaces, uppercase):

SELECT TRIM(UPPER(product)) AS cleaned_product  
FROM sales;  

Numeric Functions

Perform calculations on numbers (integers, decimals, etc.).

FunctionDescriptionExampleResult
ROUND(number, decimals)Rounds to decimals places (default: 0)ROUND(123.456, 2)123.46
CEIL(number)Rounds up to the nearest integerCEIL(4.2)5
FLOOR(number)Rounds down to the nearest integerFLOOR(4.9)4
ABS(number)Returns absolute valueABS(-7.5)7.5

Example: Round sale amounts to 2 decimal places for currency:

SELECT amount, ROUND(amount, 2) AS rounded_amount  
FROM sales;  

Date/Time Functions

Work with dates, times, and timestamps.

FunctionDescriptionExampleResult (depends on current time)
NOW()Returns current date and time (timestamp)NOW()2023-10-05 14:30:00.123456
CURRENT_DATEReturns current date (no time)CURRENT_DATE2023-10-05
EXTRACT(field FROM date)Extracts a part of a date (e.g., year, month)EXTRACT(YEAR FROM '2023-10-05'::DATE)2023
TO_CHAR(date, format)Formats a date/time as a stringTO_CHAR('2023-10-05'::DATE, 'FMMonth DD, YYYY')'October 05, 2023'
AGE(date1, date2)Calculates the interval between two datesAGE(NOW(), '2023-01-'01'::DATE)9 mons 4 days (approx)

Example: Format sale dates as “Month Day, Year”:

SELECT TO_CHAR(sale_date, 'FMMonth DD, YYYY') AS formatted_date  
FROM sales;  

Aggregate Functions

Calculate a single result from a set of rows (e.g., sum, average). Often used with GROUP BY.

FunctionDescriptionExampleResult
COUNT(column)Counts non-null values in a columnCOUNT(customer_id)Total number of customers (non-null)
SUM(column)Sums numeric valuesSUM(amount)Total sales amount
AVG(column)Calculates average of numeric valuesAVG(amount)Average sale amount
MIN(column)Returns smallest valueMIN(amount)Smallest sale amount
MAX(column)Returns largest valueMAX(amount)Largest sale amount

Example: Calculate total, average, min, and max sales per product:

SELECT product,  
       COUNT(*) AS total_sales,  
       SUM(amount) AS total_revenue,  
       AVG(amount) AS avg_sale,  
       MIN(amount) AS min_sale,  
       MAX(amount) AS max_sale  
FROM sales  
GROUP BY product;  

Array & JSON Functions

PostgreSQL natively supports arrays and JSON, with functions to manipulate them.

Array Functions

FunctionDescriptionExampleResult
ARRAY_AGG(column)Aggregates values into an arrayARRAY_AGG(product){Laptop,Phone,Tablet} (array of products)
UNNEST(array)Expands an array into rowsUNNEST(ARRAY['a', 'b', 'c'])a, b, c (each in a row)

JSON Functions

FunctionDescriptionExampleResult
jsonb_extract_path_text(jsonb_column, 'key')Extracts text from a JSONB fieldjsonb_extract_path_text(customer_data, 'email')'[email protected]' (if customer_data has {"email": "[email protected]"})

Advanced Functions

Once you’re comfortable with essentials, explore these advanced but powerful functions.

Window Functions

Window functions perform calculations across a set of table rows related to the current row (without grouping them into a single result). Common use cases: ranking, row numbering, running totals.

FunctionDescriptionExample
ROW_NUMBER() OVER (ORDER BY column)Assigns a unique row number (1, 2, 3…) ordered by columnROW_NUMBER() OVER (ORDER BY amount DESC) (rank sales by amount)
RANK() OVER (ORDER BY column)Assigns rank (ties get same rank, next rank skips)RANK() OVER (ORDER BY amount DESC)
SUM(column) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)Running total (sum up to current row)SUM(amount) OVER (ORDER BY sale_date)

Example: Rank products by total sales (descending):

SELECT product,  
       SUM(amount) AS total_revenue,  
       RANK() OVER (ORDER BY SUM(amount) DESC) AS revenue_rank  
FROM sales  
GROUP BY product;  

Conditional Functions

Handle logic based on conditions (e.g., NULL values, custom rules).

FunctionDescriptionExampleResult
CASEConditional logic (like if-else)CASE WHEN amount > 500 THEN 'High' ELSE 'Low' END AS sale_category'High' or 'Low'
COALESCE(value1, value2, ...)Returns first non-null valueCOALESCE(customer_email, '[email protected]')Uses customer_email if not null; else 'no-email...'
NULLIF(value1, value2)Returns NULL if value1 = value2; else value1NULLIF(amount, 0)NULL if amount is 0; else amount

Example: Categorize sales and handle missing emails:

SELECT customer_name,  
       COALESCE(customer_email, '[email protected]') AS email,  
       CASE  
           WHEN amount > 1000 THEN 'Premium'  
           WHEN amount > 500 THEN 'Standard'  
           ELSE 'Basic'  
       END AS sale_tier  
FROM sales;  

Practical Examples: Putting It All Together

Let’s apply what we’ve learned with a realistic scenario. Suppose we have a sales table with:

ColumnTypeDescription
idINTUnique sale ID
productVARCHARProduct sold
sale_dateTIMESTAMPDate/time of sale
amountNUMERICSale amount (USD)
customer_nameVARCHARCustomer’s name
customer_emailVARCHARCustomer’s email (may be NULL)

Example 1: Clean and Analyze Customer Data

-- Clean customer names (trim, uppercase) and handle missing emails  
SELECT TRIM(UPPER(customer_name)) AS cleaned_name,  
       COALESCE(customer_email, '[email protected]') AS email,  
       COUNT(*) AS total_purchases,  
       SUM(amount) AS total_spent  
FROM sales  
GROUP BY cleaned_name, email  
ORDER BY total_spent DESC  
LIMIT 10; -- Top 10 customers  

Example 2: Monthly Sales Report

-- Aggregate sales by month/year, format dates, calculate metrics  
SELECT TO_CHAR(sale_date, 'YYYY-MM') AS sale_month,  
       COUNT(*) AS total_sales,  
       SUM(amount) AS total_revenue,  
       AVG(amount) AS avg_sale,  
       MAX(amount) AS largest_sale,  
       -- Categorize monthly revenue  
       CASE  
           WHEN SUM(amount) > 10000 THEN 'Excellent'  
           WHEN SUM(amount) > 5000 THEN 'Good'  
           ELSE 'Low'  
       END AS revenue_tier  
FROM sales  
GROUP BY sale_month  
ORDER BY sale_month;  

Example 3: Rank Products by Monthly Sales

-- Use window functions to rank products within each month  
WITH monthly_sales AS (  
    SELECT TO_CHAR(sale_date, 'YYYY-MM') AS sale_month,  
           product,  
           SUM(amount) AS revenue  
    FROM sales  
    GROUP BY sale_month, product  
)  
SELECT sale_month,  
       product,  
       revenue,  
       RANK() OVER (PARTITION BY sale_month ORDER BY revenue DESC) AS monthly_rank  
FROM monthly_sales  
ORDER BY sale_month, monthly_rank;  

Best Practices for Using Functions and Operators

To get the most out of PostgreSQL’s built-in tools:

  1. Prioritize Built-In Functions: They are optimized for performance (e.g., SUM() is faster than looping through rows in a custom script).
  2. Mind Data Types: Ensure functions match the data type of your columns (e.g., TO_CHAR() for dates, not numbers).
  3. Handle NULLs Carefully: Use COALESCE(), NULLIF(), or IS NULL to avoid unexpected results (e.g., NULL + 5 returns NULL).
  4. Test Edge Cases: For example, AVG() ignores NULLs, but COUNT(*) includes all rows (even with NULLs).
  5. Use GROUP BY with Aggregates: Always include non-aggregated columns in GROUP BY to avoid errors (e.g., SELECT product, SUM(amount) requires GROUP BY product).

Conclusion

PostgreSQL’s built-in functions and operators are indispensable tools for anyone working with data. From simple arithmetic to complex window functions, they streamline query writing, improve performance, and unlock powerful analysis capabilities.

As a beginner, focus on mastering the essentials first—arithmetic/comparison operators, string/numeric functions, and aggregates. Once comfortable, explore advanced topics like window functions and JSON manipulation. The key is practice: experiment with your own data, write queries, and refer to the official documentation for deeper dives.

Happy querying!

References