PostgreSQL Query Cookbook
Advanced open-source object-relational database system emphasizing extensibility and standards compliance. 10 production-tested query recipes ready to copy and execute.
1. Upsert Record with ON CONFLICT
Insert a new row or update existing row columns when primary key conflicts.
INSERT INTO user_stats (user_id, login_count, last_login)
VALUES (42, 1, NOW())
ON CONFLICT (user_id) DO UPDATE SET
login_count = user_stats.login_count + 1,
last_login = EXCLUDED.last_login; 2. Query Nested JSONB Properties
Filter rows based on deeply nested JSON key values using arrow operators.
SELECT id, metadata->>'title' AS title
FROM documents
WHERE metadata @> '{"status": "published", "author": "Alex"}'; 3. Group Values into Delimited List
Aggregate text rows into a single comma-separated list per group.
SELECT department_id,
STRING_AGG(first_name, ', ' ORDER BY first_name) AS team_members
FROM employees
GROUP BY department_id; 4. Window Functions for Lead/Lag Analysis
Compute previous and next period row values without self-joins.
SELECT sale_date, amount,
LAG(amount, 1) OVER (ORDER BY sale_date) AS prev_amount,
amount - LAG(amount, 1) OVER (ORDER BY sale_date) AS diff
FROM daily_sales; 5. Create Range Partitioned Table
Divide large tables into date range partitions for query pruning.
CREATE TABLE sales_log (
id BIGSERIAL,
sale_date DATE NOT NULL,
amount NUMERIC(10,2)
) PARTITION BY RANGE (sale_date);
CREATE TABLE sales_2026_q1 PARTITION OF sales_log
FOR VALUES FROM ('2026-01-01') TO ('2026-04-01'); 6. Full-Text Search with tsvector
Perform natural language text matching with rank scoring.
SELECT title, ts_rank(to_tsvector('english', body), query) AS rank
FROM articles, to_tsquery('english', 'database & performance') query
WHERE to_tsvector('english', body) @@ query
ORDER BY rank DESC; 7. Recursive CTE for Hierarchy Trees
Traverse employee-manager organizational hierarchies recursively.
WITH RECURSIVE org_tree AS (
SELECT id, name, manager_id, 1 AS level
FROM employees WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id, o.level + 1
FROM employees e JOIN org_tree o ON e.manager_id = o.id
)
SELECT * FROM org_tree ORDER BY level, id; 8. Find Running & Blocked Queries
Inspect active database locks and long-running client sessions.
SELECT pid, now() - query_start AS duration, query, state
FROM pg_stat_activity
WHERE state != 'idle' AND now() - query_start > INTERVAL '5 seconds'
ORDER BY duration DESC; 9. Check Size of Tables & Indexes
Retrieve total disk space consumption for database tables.
SELECT relname AS table_name,
pg_size_pretty(pg_total_relation_size(relid)) AS total_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC; 10. Generate Date Ranges with generate_series
Create continuous date series tables for zero-filling missing trend data.
SELECT generate_series(
'2026-01-01'::date,
'2026-01-07'::date,
'1 day'::interval
)::date AS calendar_day; Test your PostgreSQL architectural knowledge!
Practice key concepts, memory structures, and indexing questions with flashcards.