psql -d appdbUse environment variables like PGHOST, PGPORT, PGUSER, and PGPASSWORD to avoid repeating connection flags.
Core PostgreSQL commands, SQL patterns, and object management for daily engineering work.
Launch psql and explore databases, schemas, and tables.
psql -d appdbUse environment variables like PGHOST, PGPORT, PGUSER, and PGPASSWORD to avoid repeating connection flags.
psql postgresql://appuser:secret@localhost:5432/appdbUseful for scripts and for matching application connection strings.
\lA common first command after connecting to a server.
\duUseful when checking login capability, superuser privileges, or group roles.
\dnSee summary for usage details.
\dt *.*Use patterns like `\dt public.*` to limit output.
\d+ public.usersSee summary for usage details.
\x autoSee summary for usage details.
\timing onSee summary for usage details.
psql -d appdb -f schema.sqlSee summary for usage details.
Create, alter, and drop databases and roles.
CREATE DATABASE appdb;Databases are cluster-level objects and must be created from another existing database such as `postgres`.
CREATE DATABASE appdb OWNER appuser TEMPLATE template0 ENCODING 'UTF8';See summary for usage details.
ALTER DATABASE appdb RENAME TO appdb_prod;Cannot rename the currently connected database.
DROP DATABASE appdb;See summary for usage details.
CREATE ROLE appuser WITH LOGIN PASSWORD 'secret';Roles replace the older distinction between users and groups.
CREATE ROLE readonly WITH LOGIN PASSWORD 'secret' NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT;See summary for usage details.
ALTER ROLE appuser WITH PASSWORD 'new-secret';See summary for usage details.
GRANT readonly TO analyst_user;See summary for usage details.
REVOKE readonly FROM analyst_user;See summary for usage details.
DROP ROLE readonly;Roles owning objects or memberships may need cleanup first.
Design schemas and evolve tables safely.
CREATE SCHEMA accounting AUTHORIZATION appuser;See summary for usage details.
SET search_path TO accounting, public;See summary for usage details.
CREATE TABLE public.users (
user_id bigserial PRIMARY KEY,
email text NOT NULL UNIQUE,
created_at timestamptz NOT NULL DEFAULT now()
);See summary for usage details.
CREATE TABLE events (
event_id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
payload jsonb NOT NULL
);See summary for usage details.
ALTER TABLE public.users ADD COLUMN last_login_at timestamptz;See summary for usage details.
ALTER TABLE public.users ALTER COLUMN created_at SET DEFAULT now();See summary for usage details.
ALTER TABLE public.users ALTER COLUMN email SET NOT NULL;Existing rows must already satisfy the constraint.
ALTER TABLE orders ADD CONSTRAINT orders_total_nonnegative CHECK (total_amount >= 0);See summary for usage details.
ALTER TABLE public.users RENAME TO app_users;See summary for usage details.
DROP TABLE IF EXISTS public.temp_import;See summary for usage details.
Common DML patterns for application and admin work.
INSERT INTO public.users (email) VALUES ('a@example.com');See summary for usage details.
INSERT INTO public.users (email)
VALUES ('a@example.com'), ('b@example.com'), ('c@example.com');See summary for usage details.
INSERT INTO public.users (email)
VALUES ('d@example.com')
RETURNING user_id, email, created_at;See summary for usage details.
INSERT INTO public.users (email)
VALUES ('a@example.com')
ON CONFLICT (email) DO UPDATE
SET created_at = now();See summary for usage details.
UPDATE public.users SET last_login_at = now() WHERE user_id = 42;See summary for usage details.
UPDATE orders o
SET customer_tier = c.tier
FROM customers c
WHERE o.customer_id = c.customer_id;See summary for usage details.
DELETE FROM sessions WHERE expires_at < now();See summary for usage details.
DELETE FROM jobs WHERE status = 'done' RETURNING job_id;See summary for usage details.
MERGE INTO inventory AS i
USING inventory_stage AS s
ON i.sku = s.sku
WHEN MATCHED THEN UPDATE SET qty = s.qty
WHEN NOT MATCHED THEN INSERT (sku, qty) VALUES (s.sku, s.qty);See summary for usage details.
TRUNCATE TABLE audit_log RESTART IDENTITY;See summary for usage details.
Frequently searched SQL patterns in PostgreSQL.
SELECT user_id, email FROM public.users ORDER BY user_id DESC LIMIT 20;See summary for usage details.
SELECT DISTINCT ON (customer_id)
customer_id, order_id, created_at
FROM orders
ORDER BY customer_id, created_at DESC;See summary for usage details.
SELECT o.order_id, c.name
FROM orders o
JOIN customers c ON c.customer_id = o.customer_id;See summary for usage details.
SELECT c.customer_id, o.order_id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id;See summary for usage details.
SELECT customer_id, count(*) AS order_count
FROM orders
GROUP BY customer_id
HAVING count(*) >= 5;See summary for usage details.
SELECT *, row_number() OVER (PARTITION BY customer_id ORDER BY created_at DESC)
FROM orders;See summary for usage details.
WITH recent_orders AS (
SELECT * FROM orders WHERE created_at >= now() - interval '7 days'
)
SELECT customer_id, count(*)
FROM recent_orders
GROUP BY customer_id;See summary for usage details.
WITH RECURSIVE nums(n) AS (
VALUES (1)
UNION ALL
SELECT n + 1 FROM nums WHERE n < 10
)
SELECT * FROM nums;See summary for usage details.
SELECT user_id, unnest(tags) AS tag FROM user_profiles;See summary for usage details.
SELECT payload->>'event_type' AS event_type FROM events;See summary for usage details.
Performance-critical DDL patterns and integrity rules.
CREATE INDEX idx_orders_customer_id ON orders (customer_id);See summary for usage details.
CREATE INDEX CONCURRENTLY idx_orders_created_at ON orders (created_at);Use outside a transaction block.
CREATE UNIQUE INDEX idx_users_email_unique ON public.users (email);See summary for usage details.
CREATE INDEX idx_orders_open_only ON orders (created_at) WHERE status = 'open';See summary for usage details.
CREATE INDEX idx_users_lower_email ON public.users ((lower(email)));See summary for usage details.
CREATE INDEX idx_events_payload_gin ON events USING GIN (payload jsonb_path_ops);See summary for usage details.
ALTER TABLE invoices ADD CONSTRAINT invoices_pkey PRIMARY KEY (invoice_id);See summary for usage details.
ALTER TABLE orders
ADD CONSTRAINT orders_customer_fk
FOREIGN KEY (customer_id)
REFERENCES customers (customer_id)
ON DELETE RESTRICT;See summary for usage details.
ALTER TABLE public.users ADD CONSTRAINT users_email_key UNIQUE (email);See summary for usage details.
DROP INDEX IF EXISTS idx_orders_open_only;See summary for usage details.
Reusable logic and database programmability.
CREATE VIEW active_users AS
SELECT user_id, email
FROM public.users
WHERE deleted_at IS NULL;See summary for usage details.
CREATE MATERIALIZED VIEW daily_sales AS
SELECT date_trunc('day', created_at) AS day, sum(total_amount) AS revenue
FROM orders
GROUP BY 1;See summary for usage details.
REFRESH MATERIALIZED VIEW CONCURRENTLY daily_sales;Requires a unique index for concurrent refresh.
CREATE FUNCTION public.user_email_domain(email text)
RETURNS text
LANGUAGE sql
AS $$
SELECT split_part(email, '@', 2);
$$;See summary for usage details.
CREATE OR REPLACE FUNCTION set_updated_at()
RETURNS trigger AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;See summary for usage details.
CREATE TRIGGER trg_users_updated_at
BEFORE UPDATE ON public.users
FOR EACH ROW
EXECUTE FUNCTION set_updated_at();See summary for usage details.
CREATE EXTENSION IF NOT EXISTS pgcrypto;See summary for usage details.
\dxSee summary for usage details.
COMMENT ON TABLE public.users IS 'Application users';See summary for usage details.
DROP FUNCTION IF EXISTS public.user_email_domain(text);See summary for usage details.
Popular PostgreSQL-specific data types and expressions.
SELECT jsonb_build_object('user_id', user_id, 'email', email) FROM public.users LIMIT 5;See summary for usage details.
UPDATE events
SET payload = jsonb_set(payload, '{status}', '"processed"', true)
WHERE event_id = 1;See summary for usage details.
SELECT * FROM events WHERE payload @> '{"event_type":"signup"}'::jsonb;See summary for usage details.
UPDATE user_profiles SET tags = array_append(tags, 'vip') WHERE user_id = 42;See summary for usage details.
SELECT * FROM user_profiles WHERE 'vip' = ANY(tags);See summary for usage details.
SELECT date_trunc('hour', created_at) AS hour, count(*)
FROM events
GROUP BY 1
ORDER BY 1;See summary for usage details.
SELECT now() - interval '30 days';See summary for usage details.
SELECT created_at AT TIME ZONE 'UTC' AT TIME ZONE 'America/Los_Angeles'
FROM events
LIMIT 10;See summary for usage details.
SELECT generate_series(date '2026-01-01', date '2026-01-07', interval '1 day');See summary for usage details.
SELECT user_id, COALESCE(display_name, email) AS name FROM public.users;See summary for usage details.