AI Generate PostgreSQL docs instantly

PostgreSQL Cheat Sheet

Quick reference guide with copy-paste ready code snippets

Try DocuWriter Free

Data Types

6 snippets

PostgreSQL-specific data types

UUID

CREATE TABLE users (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  name TEXT NOT NULL
);

JSONB

CREATE TABLE events (
  id SERIAL PRIMARY KEY,
  data JSONB NOT NULL DEFAULT '{}'
);

Arrays

CREATE TABLE posts (
  id SERIAL PRIMARY KEY,
  tags TEXT[] DEFAULT '{}'
);

ENUM

CREATE TYPE status AS ENUM ('draft', 'published', 'archived');
ALTER TABLE posts ADD COLUMN status status DEFAULT 'draft';

INET & CIDR

SELECT '192.168.1.0/24'::cidr >> '192.168.1.5'::inet;
-- true (contains)

Interval

SELECT NOW() - INTERVAL '30 days' AS last_month;
SELECT age('2026-01-01', '1990-05-15');

JSONB Operations

6 snippets

Query and manipulate JSON data

Extract Value

SELECT data->'name' AS json_val,
       data->>'name' AS text_val
FROM events;

Nested Path

SELECT data#>>'{address,city}' FROM events;
-- Deep path extraction as text

Containment

SELECT * FROM events
WHERE data @> '{"type": "click"}'::jsonb;

Key Exists

SELECT * FROM events WHERE data ? 'email';
-- Has key 'email'

Update JSONB

UPDATE events
SET data = jsonb_set(data, '{status}', '"active"')
WHERE id = 1;

Aggregate

SELECT jsonb_agg(name) FROM users;
SELECT jsonb_object_agg(key, value) FROM pairs;

Array Operations

6 snippets

Work with PostgreSQL arrays

ANY / ALL

SELECT * FROM posts WHERE 'sql' = ANY(tags);
SELECT * FROM posts WHERE 5 > ALL(scores);

Array Agg

SELECT author, array_agg(title)
FROM posts GROUP BY author;

Unnest

SELECT unnest(tags) AS tag FROM posts;
-- Expand array to rows

Overlap

SELECT * FROM posts
WHERE tags && ARRAY['sql','python'];
-- Arrays share elements

Contains

SELECT * FROM posts
WHERE tags @> ARRAY['sql','python'];
-- Contains all listed

Append / Remove

UPDATE posts SET tags = array_append(tags, 'new');
UPDATE posts SET tags = array_remove(tags, 'old');

Tired of looking up syntax?

DocuWriter.ai generates documentation and explains code using AI.

Try Free

CTEs & Recursive Queries

4 snippets

Common Table Expressions

Basic CTE

WITH active_users AS (
  SELECT * FROM users WHERE active = true
)
SELECT * FROM active_users WHERE created_at > NOW() - INTERVAL '7 days';

Recursive CTE

WITH RECURSIVE tree AS (
  SELECT id, name, parent_id, 0 AS depth
  FROM categories WHERE parent_id IS NULL
  UNION ALL
  SELECT c.id, c.name, c.parent_id, t.depth + 1
  FROM categories c JOIN tree t ON c.parent_id = t.id
)
SELECT * FROM tree;

Materialized

WITH active AS MATERIALIZED (
  SELECT * FROM users WHERE active
)
SELECT * FROM active;  -- Forces subquery evaluation

Multiple CTEs

WITH
  recent AS (SELECT * FROM orders WHERE date > NOW() - '30d'::interval),
  totals AS (SELECT user_id, SUM(amount) FROM recent GROUP BY user_id)
SELECT u.name, t.sum FROM users u JOIN totals t ON u.id = t.user_id;

Indexing

6 snippets

Index types and strategies

B-tree (default)

CREATE INDEX idx_email ON users(email);
CREATE UNIQUE INDEX idx_uniq ON users(email);

GIN (JSONB/Array/FTS)

CREATE INDEX idx_data ON events USING GIN(data);
CREATE INDEX idx_tags ON posts USING GIN(tags);

Partial Index

CREATE INDEX idx_active ON users(email)
WHERE active = true;
-- Only indexes matching rows

Expression Index

CREATE INDEX idx_lower ON users(LOWER(email));
-- Index on computed value

Covering Index

CREATE INDEX idx_cover ON orders(user_id)
INCLUDE (total, created_at);
-- Index-only scans

BRIN (large tables)

CREATE INDEX idx_ts ON logs USING BRIN(created_at);
-- Compact index for sorted data

Partitioning

4 snippets

Table partitioning strategies

Range Partition

CREATE TABLE logs (
  id BIGSERIAL, ts TIMESTAMPTZ, msg TEXT
) PARTITION BY RANGE (ts);

CREATE TABLE logs_2026_01 PARTITION OF logs
  FOR VALUES FROM ('2026-01-01') TO ('2026-02-01');

List Partition

CREATE TABLE orders (
  id SERIAL, region TEXT, amount NUMERIC
) PARTITION BY LIST (region);

CREATE TABLE orders_us PARTITION OF orders
  FOR VALUES IN ('us-east', 'us-west');

Hash Partition

CREATE TABLE sessions (
  id UUID, data JSONB
) PARTITION BY HASH (id);

CREATE TABLE sessions_0 PARTITION OF sessions
  FOR VALUES WITH (MODULUS 4, REMAINDER 0);

Attach / Detach

ALTER TABLE logs ATTACH PARTITION logs_old
  FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
ALTER TABLE logs DETACH PARTITION logs_old;

Extensions

5 snippets

Popular PostgreSQL extensions

pg_trgm (fuzzy)

CREATE EXTENSION pg_trgm;
SELECT * FROM products
WHERE name % 'postgre'
ORDER BY similarity(name, 'postgre') DESC;

uuid-ossp

CREATE EXTENSION "uuid-ossp";
SELECT uuid_generate_v4();
-- Or use built-in: gen_random_uuid()

pgcrypto

CREATE EXTENSION pgcrypto;
SELECT crypt('password', gen_salt('bf'));
SELECT (crypt('password', hash) = hash) AS valid;

citext

CREATE EXTENSION citext;
ALTER TABLE users ALTER COLUMN email TYPE citext;
-- Case-insensitive text

pgvector

CREATE EXTENSION vector;
CREATE TABLE items (id SERIAL, embedding vector(1536));
SELECT * FROM items ORDER BY embedding <=> '[0.1,0.2,...]' LIMIT 5;

Performance

5 snippets

Query analysis and tuning

EXPLAIN ANALYZE

EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT * FROM users WHERE email = 'a@b.com';

Table Stats

SELECT relname, n_live_tup, n_dead_tup,
  last_vacuum, last_autovacuum
FROM pg_stat_user_tables;

Index Usage

SELECT indexrelname, idx_scan, idx_tup_read
FROM pg_stat_user_indexes
WHERE idx_scan = 0;  -- Unused indexes

VACUUM

VACUUM ANALYZE users;      -- Update stats
VACUUM FULL users;         -- Reclaim space (locks table)
SELECT pg_size_pretty(pg_total_relation_size('users'));

Slow Queries

CREATE EXTENSION pg_stat_statements;
SELECT query, calls, mean_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC LIMIT 10;

Administration

5 snippets

psql commands and admin tasks

psql Commands

\l          -- List databases
\dt         -- List tables
\d+ table   -- Describe table
\di         -- List indexes
\df         -- List functions
\x          -- Toggle expanded output

Backup & Restore

pg_dump -Fc mydb > backup.dump
pg_restore -d mydb backup.dump
pg_dump --schema-only mydb > schema.sql

Roles & Grants

CREATE ROLE readonly LOGIN PASSWORD 'secret';
GRANT CONNECT ON DATABASE mydb TO readonly;
GRANT USAGE ON SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

Kill Query

SELECT pid, query, state FROM pg_stat_activity
WHERE state = 'active';
SELECT pg_cancel_backend(pid);   -- Graceful
SELECT pg_terminate_backend(pid); -- Force

Generate Series

SELECT generate_series('2026-01-01'::date, '2026-12-31', '1 month');
SELECT generate_series(1, 100) AS n;

Advanced Queries

5 snippets

LATERAL, FILTER, grouping sets

LATERAL Join

SELECT u.name, r.title FROM users u,
LATERAL (
  SELECT title FROM posts WHERE author_id = u.id
  ORDER BY created_at DESC LIMIT 3
) r;

FILTER Clause

SELECT
  COUNT(*) AS total,
  COUNT(*) FILTER (WHERE status = 'active') AS active,
  AVG(score) FILTER (WHERE score > 0) AS avg_positive
FROM users;

GROUPING SETS

SELECT region, product, SUM(sales)
FROM orders
GROUP BY GROUPING SETS (
  (region, product), (region), (product), ()
);

COPY (bulk I/O)

COPY users(name, email) FROM '/tmp/users.csv' CSV HEADER;
COPY (SELECT * FROM users) TO '/tmp/export.csv' CSV HEADER;

Upsert

INSERT INTO users (email, name) VALUES ('a@b.com', 'Alice')
ON CONFLICT (email)
DO UPDATE SET name = EXCLUDED.name, updated_at = NOW();

More Cheat Sheets

FAQ

Frequently asked questions

What is a PostgreSQL cheat sheet?

A PostgreSQL cheat sheet is a quick reference guide containing the most commonly used syntax, functions, and patterns in PostgreSQL. It helps developers quickly look up syntax without searching through documentation.

How do I learn PostgreSQL quickly?

Start with the basics: variables, control flow, and functions. Use this cheat sheet as a reference while practicing. For faster learning, try DocuWriter.ai to automatically explain code and generate documentation as you learn.

What are the most important PostgreSQL concepts?

Key PostgreSQL concepts include variables and data types, control flow (if/else, loops), functions, error handling, and working with data structures like arrays and objects/dictionaries.

How can I document my PostgreSQL code?

Use inline comments for complex logic, docstrings for functions and classes, and README files for projects. DocuWriter.ai can automatically generate professional documentation from your PostgreSQL code using AI.

Related resources

Stop memorizing. Start shipping.

Generate PostgreSQL Docs with AI

DocuWriter.ai automatically generates comments, docstrings, and README files for your code.

Auto-generate comments
Create README files
Explain complex code
API documentation
Start Free - No Credit Card

Join 33,700+ developers saving hours every week