Monetary Types

Postgresql datatypes

Video Locked

Please log in to watch this video

Log In
Chapter Info
Course The Ultimate PostGIS course
Module Postgresql datatypes
Chapter Monetary Types

Chapter Content

Introduction to the MONEY Type

The money type in PostgreSQL is designed to store currency values with fixed fractional precision.

Syntax

amount MONEY

It stores values like $123.45, depending on your locale.

Creating a Table with MONEY Type

CREATE TABLE salaries (
  id SERIAL PRIMARY KEY,
  employee_name TEXT,
  monthly_salary MONEY
);

INSERT INTO salaries (employee_name, monthly_salary) VALUES
('Alice', '$2500.00'),
('Bob', '$3000.50'),
('Charlie', '$2750.25');

Querying and Arithmetic with MONEY

-- Add bonus of $200 to each salary
SELECT employee_name, monthly_salary + '$200' AS salary_with_bonus
FROM salaries;

-- Annual salary
SELECT employee_name, monthly_salary * 12 AS annual_salary
FROM salaries;

Locale Formatting of MONEY

The format of money depends on the lc_monetary setting.

SHOW lc_monetary;

Create database with specific locale:

createdb salary_db --lc-monetary='de_DE.UTF-8' --template=template0

In SQL:

CREATE DATABASE salary_db
  WITH TEMPLATE = template0
  LC_MONETARY = 'de_DE.UTF-8'
  ENCODING = 'UTF8';

Converting MONEY to Numeric

-- Convert for calculations
SELECT employee_name, monthly_salary::NUMERIC * 0.18 AS tax
FROM salaries;

Best Practices

  • Use money for fixed, simple currency storage.
  • Use NUMERIC for more control and currency conversion.
  • Format output using TO_CHAR() when needed:
SELECT employee_name, TO_CHAR(monthly_salary, 'FM999999.00') AS formatted_salary
FROM salaries;

Limitations of MONEY Type

  • Limited to a single currency symbol
  • Locale-specific formatting may be confusing in multi-region apps
  • Does not support multi-currency storage cleanly

Alternatives to MONEY Type

Prefer NUMERIC(10,2) with controlled formatting:

CREATE TABLE invoices (
  id SERIAL PRIMARY KEY,
  client TEXT,
  total_amount NUMERIC(10, 2)
);

INSERT INTO invoices (client, total_amount) VALUES
('Client A', 12345.67),
('Client B', 98765.43);

SELECT client, TO_CHAR(total_amount, 'FM999,999.00') AS formatted_total
FROM invoices;

Decimal and Thousands Separator

The default locale en_US.UTF-8 uses dot . as decimal and comma , as thousands separator.

To use comma as decimal (European style):

createdb euro_db --lc-monetary='de_DE.UTF-8' --template=template0