psql -U user -d dbConnect as a specific user to a database.psql -h host -p 5432 -U user -d db★Connect to a remote server.psql -c "SQL"Run one command, then exit.psql db -f file.sqlExecute commands from a script file.sudo -u postgres psql★Local shortcut: become the postgres superuser.\c dbname★Switch databases inside an open session.\conninfoShow the current connection's details.\q★Quit psql.
\l★List all databases.\dt★List tables in the current schema.\d table★Describe a table: columns, indexes, FKs.\d+ table…plus disk size and storage details.\dnList schemas.\diList indexes.\dvList views.\dfList functions.\du★List roles and their attributes.\x★Toggle expanded (vertical) row output.\timingToggle display of each query's run time.\! cmdRun a shell command without leaving psql.\i fileExecute SQL from a file.
CREATE DATABASE name;★Create a new database.CREATE DATABASE name OWNER user;…owned by a specific role.ALTER DATABASE old RENAME TO new;Rename a database.DROP DATABASE name;destroysDelete a database permanently.CREATE SCHEMA IF NOT EXISTS name;A namespace to group related tables.DROP SCHEMA name CASCADE;destroysDelete a schema and everything in it.
CREATE TABLE t (col type, …);★Define a new table.id SERIAL PRIMARY KEY★Auto-incrementing key (legacy syntax).id INT GENERATED ALWAYS AS IDENTITYModern, SQL-standard auto-increment.FOREIGN KEY (col) REFERENCES other(id)Link this table to another.ALTER TABLE t ADD COLUMN c type;★Add a column.ALTER TABLE t RENAME COLUMN a TO b;Rename a column.ALTER TABLE t ALTER COLUMN c TYPE type;Change a column's data type.ALTER TABLE t DROP COLUMN c;Remove a column.ALTER TABLE t RENAME TO new;Rename the table itself.DROP TABLE IF EXISTS t CASCADE;destroysDelete a table + dependent objects.TRUNCATE TABLE t;destroysWipe all rows instantly, keep structure.
PRIMARY KEY★Unique + NOT NULL row identifier.UNIQUENo duplicate values (NULLs exempt).NOT NULLColumn can never be empty.CHECK (expr)Row must satisfy a boolean condition.FOREIGN KEY … REFERENCES …★Enforce a link to another table's key.ADD CONSTRAINT name …Name and attach a constraint after creation.
CREATE VIEW v AS SELECT …;★A saved query you can select from like a table.CREATE MATERIALIZED VIEW mv AS SELECT …;★Stores the results on disk — fast reads, stale until refreshed.REFRESH MATERIALIZED VIEW [CONCURRENTLY] mv;Recompute a matview; CONCURRENTLY avoids locking readers.CREATE TYPE mood AS ENUM ('low','ok','high');★A custom enumerated type with a fixed value set.CREATE DOMAIN email AS TEXT CHECK (VALUE ~ '@');A reusable type = base type + constraint.CREATE SEQUENCE s START 1 INCREMENT 1;A standalone counter;nextval('s')to draw from it.c type GENERATED ALWAYS AS (expr) STOREDA computed column, persisted on write.COMMENT ON TABLE t IS 'note';Attach documentation to any object.
CREATE TABLE t (…) PARTITION BY RANGE (col);★Declare a partitioned parent (RANGE / LIST / HASH).CREATE TABLE t_2025 PARTITION OF t FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');★Attach a range child partition.… PARTITION OF t FOR VALUES IN ('AP','TN');A LIST partition for discrete values.… PARTITION OF t FOR VALUES WITH (MODULUS 4, REMAINDER 0);A HASH partition, spreading rows evenly.ALTER TABLE t DETACH PARTITION t_2025;Remove a partition without dropping its data.
INTEGER / BIGINT / NUMERIC(p,s)★Whole numbers & exact decimals.VARCHAR(n) / TEXT★Bounded vs. unbounded text.BOOLEANtrue / false.DATE / TIME / TIMESTAMPTZ★Calendar date, time, timestamp+zone.JSON / JSONB★Document data — JSONB is binary & indexable.UUIDUniversally unique identifier.integer[]Array of any base type.inet / cidr / macaddrNetwork address types.
SELECT col1, col2 FROM t;★Fetch specific columns.SELECT * FROM t;Fetch every column.SELECT DISTINCT col FROM t;Unique values only.… ORDER BY col [ASC|DESC];★Sort the result set.… LIMIT n OFFSET m;★Page through results.col AS aliasRename a column in the output.
WHERE col = value★Exact match.WHERE col BETWEEN a AND bInclusive numeric/date range.WHERE col IN (a, b, c)Matches any of several values.WHERE col LIKE '%abc%'★Pattern match, case-sensitive.WHERE col ILIKE '%abc%'Pattern match, case-insensitive.WHERE col IS [NOT] NULL★Missing-value checks — never use= NULL.WHERE condn1 [AND|OR] condn2Combine multiple conditions.
JOIN b ON a.id = b.a_id★INNER join (the default) — matches only.LEFT JOIN b ON …★All of A, plus matches from B.RIGHT JOIN b ON …All of B, plus matches from A.FULL JOIN b ON …Everything from both sides.CROSS JOIN bEvery row of A × every row of B.a JOIN b USING (col)Shorthand when join-column names match.
WITH cte AS (SELECT …) SELECT * FROM cte;★Name a subquery up front for readability & reuse.WITH RECURSIVE r AS (… UNION ALL …)★Walk trees / graphs / hierarchies (org charts, BOMs).WHERE EXISTS (SELECT 1 FROM b WHERE …)★Row-exists test — usually faster than IN for big sets.WHERE col = (SELECT MAX(col) FROM t)Scalar subquery — returns exactly one value.WHERE col = ANY(…) / ALL(…)Compare against a set (ANY = some, ALL = every).JOIN LATERAL (SELECT … WHERE x=t.id) s ON trueA subquery that can reference the outer row (top-N per group).
q1 UNION q2 / UNION ALL q2★Stack rows; ALL keeps duplicates (and is faster).q1 INTERSECT q2 / EXCEPT q2Rows in both / rows in the first but not the second.CASE WHEN c THEN a ELSE b END★Inline if/else — usable in SELECT, WHERE, ORDER BY.COUNT(*) FILTER (WHERE condn)★Conditional aggregate — cleaner than SUM(CASE…).GROUP BY ROLLUP (a, b) / CUBE (a, b)Subtotals & grand totals across group combinations.GROUP BY GROUPING SETS ((a),(b),())Several groupings in one pass.
COUNT(*) / COUNT(col) / COUNT(DISTINCT col)★Row counts, three flavors.SUM / AVG / MIN / MAX(col)★Column summaries.GROUP BY col★Roll rows up by shared value.GROUP BY col HAVING condn★Filter groups, not raw rows.STRING_AGG(col, ', ') / ARRAY_AGG(col)Fold a group's values into one string / array.
fn(…) OVER (PARTITION BY c1 ORDER BY c2)★The core shape — unlike GROUP BY, rows aren't collapsed.PARTITION BY col★Resets the window per group (optional — omit for the whole table).SUM(x) OVER (PARTITION BY c1 ORDER BY c2)★Running/partitioned total — a per-row aggregate.ROW_NUMBER() OVER (… ORDER BY col)★Sequential rank, 1,2,3… — never ties.RANK() OVER (… ORDER BY col)Rank with gaps after ties (1,2,2,4).DENSE_RANK() OVER (… ORDER BY col)Rank with no gaps after ties (1,2,2,3).LAG(col, n) / LEAD(col, n) OVER (…)★Previous / next row's value — great for deltas.FIRST_VALUE(col) / LAST_VALUE(col) OVER (…)Value at the start / end of the current frame.NTILE(4) OVER (ORDER BY col)Split rows into n roughly-equal buckets (quartiles, etc).… ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROWExplicit frame boundary — default for a running total.WINDOW w AS (…) … OVER wName a window once, reuse it across several functions.
INSERT INTO t (c1,c2) VALUES (v1,v2), (v3,v4);★Add one or many rows in a single statement.… ON CONFLICT (id) DO UPDATE SET …;★Upsert: insert, or update on key clash.… ON CONFLICT DO NOTHING;Silently skip rows that would violate a constraint.INSERT/UPDATE/DELETE … RETURNING *;★Get the affected rows back — e.g. a generated id.UPDATE t SET c=v WHERE condn;★Modify matching rows.UPDATE t SET c=b.v FROM b WHERE t.id=b.id;Update using values joined from another table.DELETE FROM t USING b WHERE t.id=b.id;Delete based on a join to another table.MERGE INTO t USING src ON … WHEN MATCHED …;SQL-standard conditional insert/update/delete (PG 15+).DELETE FROM t;careRemoves every row (logged, row-by-row).COPY t FROM 'file' CSV HEADER;Bulk-load rows from a CSV file.
BEGIN;★Start a transaction block.COMMIT;★Make changes permanent.ROLLBACK;★Undo everything since BEGIN.SAVEPOINT name;Set a mid-transaction checkpoint.ROLLBACK TO SAVEPOINT name;Undo back to that checkpoint only.SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;★Strictest level; others: READ COMMITTED (default), REPEATABLE READ.SELECT … FOR UPDATE [SKIP LOCKED];★Lock selected rows — the basis of a safe job queue.
CREATE INDEX idx ON t (col);★Speed up lookups/sorts on a column.CREATE UNIQUE INDEX idx ON t (LOWER(email));Index + enforce uniqueness on an expression.CREATE INDEX idx ON t (col) WHERE condn;Partial index over a subset of rows.DROP INDEX IF EXISTS idx;careRemove an index (reads get slower).EXPLAIN SELECT …;★Show the planner's chosen query path.EXPLAIN ANALYZE SELECT …;★Plan + actually run it, with real timings.ANALYZE t;Refresh planner statistics for a table.
CREATE ROLE r WITH LOGIN PASSWORD 'x';Create a login-capable role.CREATE USER u WITH PASSWORD 'x';★Shortcut for a login role.ALTER ROLE r WITH PASSWORD 'new';Change a role's password.GRANT SELECT, INSERT ON t TO r;★Allow specific actions on a table.GRANT ALL PRIVILEGES ON DATABASE d TO r;Grant full access to a database.REVOKE INSERT ON t FROM r;Remove a previously granted privilege.ALTER DEFAULT PRIVILEGES … GRANT SELECT ON TABLES TO r;Auto-grant on objects created later.ALTER TABLE t ENABLE ROW LEVEL SECURITY;★Turn on per-row access rules.CREATE POLICY p ON t USING (owner = current_user);Define who may see / change which rows.DROP ROLE IF EXISTS r;careDelete a role permanently.
a || b or CONCAT(a,b)★Concatenate strings (||propagates NULL; CONCAT skips it).LENGTH(s) / UPPER(s) / LOWER(s)Size and case conversion.SUBSTRING(s FROM i FOR n)Extract part of a string.REPLACE(s, 'old', 'new')Swap a substring.CURRENT_DATE / NOW() / CURRENT_TIMESTAMP★Current date/time.EXTRACT(MONTH FROM date)Pull out one component of a date.DATE_TRUNC('month', ts)★Round a timestamp down to a unit.value::type or CAST(value AS type)★Convert between types.COALESCE(a, b, default)★First non-NULL value in the list.NULLIF(a, b)Returns NULL if equal — guards against ÷0.
pg_dump -U u -d db -f db.sql★Plain-SQL logical backup.pg_dump -Fc -U u -d db -f db.dumpCustom-format backup, for use with pg_restore.pg_dumpall > all.sqlAll databases plus roles & tablespaces.psql -U u -d db -f db.sql★Restore a plain-SQL backup.pg_restore -d db db.dump -cRestore a custom-format backup.\copy t TO 'file.csv' CSV HEADER★Export a table (or query) to CSV.\copy t FROM 'file.csv' CSV HEADER★Import a CSV file into a table.
SELECT * FROM pg_stat_activity;★See active sessions & running queries.SELECT pg_cancel_backend(pid);Politely stop a running query.SELECT pg_terminate_backend(pid);forceForce-kill a connection.pg_size_pretty(pg_total_relation_size('t'))★Human-readable table size on disk.pg_size_pretty(pg_database_size('db'))Total database size.VACUUM [ANALYZE] t;★Reclaim dead-row space + refresh stats.SELECT version();Show the server version.
data -> 'key' / data ->> 'key'★Get a field as JSON (->) or as text (->>).data #> '{a,b}' / data #>> '{a,b}'Reach into a nested path (JSON / text).data @> '{"k":1}'★Containment — does the doc contain this? (GIN-indexable).data ? 'key' / data ?| array['a','b']Does a top-level key exist / any of these keys.data @? '$.items[*] ? (@.qty > 5)'JSONPath match (PG 12+).jsonb_build_object('k', v) / jsonb_build_array(…)★Assemble JSONB from columns.jsonb_set(data, '{a,b}', '10'::jsonb)Return the doc with one path updated.jsonb_agg(row) / jsonb_object_agg(k, v)Aggregate rows into one JSONB array / object.jsonb_array_elements(data) / jsonb_each(data)★Expand an array / object into rows (set-returning).CREATE INDEX ON t USING GIN (data jsonb_path_ops);★Index JSONB for fast@>/@?containment queries.
'{1,2,3}'::int[] / ARRAY[1,2,3]★Two ways to write an array literal.arr[1] / arr[2:3]Index (1-based!) or slice an array.arr @> ARRAY[2] / arr && ARRAY[2,9]★Contains / overlaps — both GIN-indexable.val = ANY(arr)★Membership test — the array equivalent of IN.array_length(arr, 1) / cardinality(arr)Element count.SELECT unnest(arr)★Expand an array into one row per element.array_agg(col) / array_to_string(arr, ',')Rows → array; array → delimited text.
to_tsvector('english', body)★Normalize text into searchable lexemes.to_tsquery('english', 'flood & relief')★Build a query with & (and), | (or), ! (not).plainto_tsquery(…) / websearch_to_tsquery(…)Parse plain / Google-style user input safely.tsvector @@ tsquery★The match operator — true if the doc matches.ts_rank(tsv, tsq) / ts_headline(…)Relevance score / highlighted snippet.CREATE INDEX ON t USING GIN (to_tsvector('english', body));★GIN index — makes@@searches fast.
CREATE FUNCTION f(a int) RETURNS int LANGUAGE sql AS $$ … $$;★A plain SQL function.LANGUAGE plpgsql AS $$ BEGIN … RETURN x; END $$;★Procedural body: variables, IF, LOOP, exceptions.CREATE PROCEDURE p() … — CALL p();A procedure can COMMIT/ROLLBACK; call it with CALL.DO $$ BEGIN … END $$;Run an anonymous procedural block once.CREATE TRIGGER trg BEFORE INSERT ON t FOR EACH ROW EXECUTE FUNCTION fn();★Fire a function on insert/update/delete.NEW.col / OLD.col / RETURN NEW;Inside a row trigger: the incoming / previous row.
CREATE EXTENSION IF NOT EXISTS name;★The generic form; list installed with\dx.pg_trgm★Trigram similarity — fuzzy search & fastILIKE '%x%'.uuid-ossp / pgcrypto★gen_random_uuid(), hashing & encryption helpers.hstoreSimple key/value pairs in one column.postgres_fdw / dblinkQuery tables in another PostgreSQL server.pg_stat_statements★Track slowest / most frequent queries for tuning.