INSERT INTO dim_customers (customer_id, name, tier)
VALUES (1, 'Acme', 'pro');
INSERT INTO dim_status (status_id, label) VALUES
(1, 'new'), (2, 'paid'), (3, 'refunded');
INSERT INTO mart_daily_revenue (day, revenue_cents)
SELECT date_trunc('day', ordered_at), SUM(amount_cents)
FROM stg_orders
GROUP BY 1;
Rules
- Always name columns.
INSERT INTO t VALUES (...) breaks the day someone
adds a column. Name them; order then doesn't matter.
INSERT..SELECT is how loads move data โ staging to mart, mart to
snapshot. Pair it with a watermark (WHERE ordered_at > :last_seen) for
incremental loads.
INSERT..SELECT + ON CONFLICT DO NOTHING makes reloads idempotent:
re-running yesterday's partition changes nothing.
- Match types explicitly (
::timestamptz, ::numeric) โ implicit casts
across engines are a top source of silent truncation.