Master Reference · relational + spatial + network · v4 · single source of truth

postgreSQL + postGIS + pgRouting cheat sheet

A comprehensive single-page reference across all five SQL sub-languages — DDL (define), DQL (query), DML (modify), DCL (permit), TCL (transact) — plus the modules that make PostgreSQL a category of its own: JSON/JSONB, arrays, full-text search, CTEs & window functions, PL/pgSQL, PostGIS spatial, and pgRouting network analysis. SQL is written top-down but executed in a fixed order; learn that order (below) and most "gotchas" dissolve.

psql client schema (DDL) data (DML) query / read admin & perf PostGIS pgRouting destructive most common

Distilled & cross-checked across: postgresql.org · postgis.net · pgrouting.org · linuxize.com · quickref.me · tigerdata.com · geeksforgeeks.org · codecademy.com · gist.github.com/yokawasa · gist.github.com/Kartones · DataCamp · LearnSQL.com / Vertabelo

Logical query processing order

You write a query SELECT…FROM…WHERE…ORDER BY — but the planner executes it in this sequence. This is why a WHERE clause can't see a SELECT alias, and why ORDER BY can.

1 FROM / JOIN build the row set 2 WHERE filter rows (no aliases) 3 GROUP BY collapse into groups 4 HAVING filter the groups 5 SELECT DISTINCT compute & dedupe columns 6 ORDER BY sort — aliases work here 7 LIMIT / OFFSET trim the final rows EXECUTION RUNS LEFT → RIGHT you typed: SELECT…FROM…WHERE…GROUP BY…HAVING…ORDER BY…LIMIT (written order is almost the reverse of run order — window functions run between step 4 and step 5)

Core SQL

The full relational toolkit: DDL (define), DQL (query), DML (modify), DCL (permit), TCL (transact), plus JSON/JSONB, arrays, full-text search, and PL/pgSQL.

01Connect & psql Flagsthe command line
02psql Meta-Commandsthe backslash family
03Databases & Schemastop-level containers
04Create & Alter Tablesstructure
05Constraintsdata integrity rules
06Views, Sequences & TypesDDL — derived & custom objects
07Table PartitioningDDL — split big tables
08Core Data Typeswhat to store columns as
09Query BasicsSELECT, sort, page
10FilteringWHERE clauses
11Joinscombine tables — see diagrams ↓
12CTEs & SubqueriesDQL — compose queries
13Set Ops, CASE & Grouping SetsDQL — combine & branch
14Aggregation & Groupingsummarize rows
15Window Functionsper-row aggregates, keep every row
16Modifying Datawrite operations
17Transactionsall-or-nothing changes
18Indexes & Performancemake reads fast
19Roles & Privilegeswho can do what
20Text, Date & Castingcommon functions
21Backup, Restore & CSVmove data in & out
22Monitoring & Maintenancekeep it healthy
23JSON & JSONBmodule — document data
24Arraysmodule — multi-value columns
25Full-Text Searchmodule — search documents
26Functions, PL/pgSQL & Triggersmodule — server-side logic
27Handy Extensionsmodule — CREATE EXTENSION

PostGIS — Spatial Extension

PostGIS turns PostgreSQL into a spatial database: new geometry/geography column types, ~300 ST_ functions, and GiST indexing over a coordinate plane or sphere.

28Setup & Geometry TypesPostGIS
29SRID, geometry vs geographythe #1 source of bugs
30Constructors & Accessorsbuild & inspect geometries
31Spatial Relationshipspredicates — see diagrams ↓
32Measurement & Processingcompute & transform
33Spatial Indexing & Loadingmake it fast, get data in

pgRouting — Network Routing

pgRouting layers graph algorithms on top of PostGIS geometries — turning a table of line segments into a routable network for shortest-path, driving-distance, and multi-stop queries, all in SQL.

34Setup & TopologypgRouting
35Shortest PathpgRouting — see diagram ↓
36Network AnalysispgRouting
Reading the Placeholdersnotation used throughout

The four core joins

Same two tables, A and B — the shaded region is what each join keeps. Based on the standard SQL join-Venn convention.

INNER JOIN

Only rows where the join condition matches on both sides.

A B A ∩ B

LEFT JOIN

Every row from A, with matches from B where they exist (else NULL).

A B all of A

RIGHT JOIN

Every row from B, with matches from A where they exist (else NULL).

A B all of B

FULL OUTER JOIN

Every row from both sides; unmatched columns come back NULL.

A B A ∪ B
GROUP BY vs. window function

Both compute an aggregate per group — but GROUP BY collapses rows down to one per group, while a window function keeps every original row and attaches the aggregate alongside it.

GROUP BY col row, row, row row, row 1 summary row / group fn() OVER (PARTITION BY col) row + agg row + agg row + agg row + agg every row kept, all 4 see the same per-partition value
PostGIS spatial index: filter, then refine

Index-aware predicates (ST_Intersects, ST_Contains, ST_Covers, ST_DWithin…) run in two phases automatically — you just write the predicate.

1 · FILTER GiST R-Tree compares bounding boxes only fast · approximate · may over-include → candidate rows 2 · REFINE exact ST_ predicate runs on candidates only slower · exact · confirms real matches → final result ST_Disjoint & ST_Relate are negations — they skip the filter phase entirely full scan — avoid on big tables ⚠ not index-aware
pgRouting: from lines to a routable network

A table of disconnected line geometries becomes a weighted graph in two steps — then pgr_dijkstra and friends can search it.

1 · TOPOLOGY pgr_createTopology assigns source/target IDs from endpoints raw lines → noded graph → edges with node IDs 2 · ROUTE pgr_dijkstra / pgr_aStar walk the weighted graph by cost graph → ordered edge sequence → shortest path result cost & reverse_cost a negative value on either column blocks that direction models one-way streets ⚠ sign = direction

Reading the four common predicates

A square (table A) and a circle (table B) — the shaded/highlighted part is what each predicate tests true for.

ST_Intersects

True if A and B share any point at all — the broadest, most common test.

A B shares any point

ST_Contains / ST_Within

True if one geometry's interior fully encloses the other.

A B A contains B

ST_Touches

True only if boundaries meet — interiors never overlap.

A B shared edge only

ST_DWithin

True if a target lies inside a buffer distance d — index-aware proximity search.

A in out within distance d

Worth memorizing

WHERE ≠ HAVINGWHERE filters rows before grouping; HAVING filters the groups
DELETE ≠ TRUNCATEDELETE is row-by-row, logged, supports WHERE; TRUNCATE is instant, no WHERE
= NULL is always falseNULL has no equality — use IS [NOT] NULL
SERIAL ≠ IDENTITYSERIAL is legacy sugar; GENERATED ALWAYS AS IDENTITY is the SQL standard
VACUUM ≠ ANALYZEVACUUM reclaims dead-row space; ANALYZE refreshes planner statistics
no USE statementPostgres has no USE db — switch with \c inside psql
UNIQUE index ≠ PRIMARY KEYboth enforce uniqueness, but UNIQUE permits one NULL
autocommit is oneach statement commits immediately unless wrapped in BEGIN…COMMIT
RANK ≠ DENSE_RANKRANK leaves gaps after ties (1,2,2,4); DENSE_RANK doesn't (1,2,2,3)
window fns run after HAVINGthey can't be used in WHERE/HAVING — wrap the query and filter in an outer SELECT
-> keeps JSON, ->> gives textuse ->> when you need to compare or cast the value; -> when you'll keep drilling in
JSONB @> wants a GIN indexcontainment & JSONPath scale only with USING GIN; a plain b-tree won't help
arrays are 1-indexedarr[1] is the first element — not arr[0] as in most languages
full-text needs @@ + a tsvectorLIKE '%x%' can't rank or stem; to_tsvector + GIN + @@ does both
MATERIALIZED VIEWs go stalethey don't auto-update — REFRESH (ideally CONCURRENTLY) on a schedule
geometry ≠ geographygeometry is planar & degrees on 4326; geography is spherical & always metres
ST_MakePoint defaults to SRID 0always wrap it: ST_SetSRID(ST_MakePoint(lon,lat), 4326)
PostGIS order is (X, Y)that's (longitude, latitude) — the reverse of how people say "lat/lon"
ST_SetSRID ≠ ST_TransformSetSRID only labels the data; Transform actually reprojects the coordinates
source/target are auto-assignedpgr_createTopology fills them in — don't hand-pick these node IDs yourself
negative cost blocks a directionreverse_cost < 0 makes an edge one-way; routing functions skip it going that way
pgr_dijkstra's first arg is SQLit's a live edge query, not a table name — must return id, source, target, cost