Shows how to store, calculate, and report Oracle-style SaaS subscription pricing tiers with pure PostgreSQL.
Oracle SaaS pricing uses subscription terms (monthly, annual), tiered unit prices, and optional discounts. Modeling the logic in PostgreSQL lets engineers run cost simulations, bill customers, and feed dashboards without leaving their data warehouse.
Create a Products
table for list price, a PriceTiers
table for quantity-based breaks, and a Subscriptions
table that records the customer’s plan, seats, and term.
Use a CTE to select the matching tier, multiply by quantity, and apply any percent or fixed discount. Wrap it in a calculate_subscription_price()
SQL function for reuse.
Add a setup_fee
column to Products
. When the function detects a new subscription (no prior invoice), it sums the tiered seat price and the one-time fee.
Aggregate Subscriptions
by term length. For monthly terms divide annualized totals by 12; for annual terms sum the yearly price directly. Use window functions for rolling 3-, 6-, or 12-month trends.
NUMERIC(12,2)
Avoid floating-point rounding by always using NUMERIC
for money. Convert to the customer’s display currency only in the UI layer.
Keep a Discounts
table keyed by subscription_id
. Handling discounts outside the pricing function complicates audits and promotions.
Insert draft tiers with a valid_from
/valid_to
range. Point the pricing function to the desired draft date to run "what-if" computations without touching production rows.
Yes. Add a currency
column to Products
and store exchange rates in a separate table. Join the rate inside the pricing function to convert on the fly.
Record the original invoice amount and seats. When seats increase mid-cycle, compute the new monthly cost, subtract the unused portion of the original amount, and bill the difference.
Yes. Index PriceTiers(product_id, min_qty, max_qty)
and Subscriptions(product_id)
. The calculation touches only one product row and one tier row per subscription.