SQL Numeric Functions
Rounding, truncating, absolute values, modulo and integer division - and the rounding rules that decide whether your invoice totals balance.
- SQL Basics
- DDL
- DML
- SELECT
- WHERE
- Functions
- NULL and Logic
- Aggregate Functions
- GROUP BY
- JOIN
- Subqueries
- Set Operations
- CTEs
- Constraints
- Keys
- Relationships
- Database Design
- Normalisation
- Views
- Window Functions
- Advanced SQL
- Procedures and Functions
- Triggers
- Temporary Tables
- Transactions
- Isolation and Locking
- Indexes
- Query Performance
- SQL Security
- SQL Dialects
- Practical SQL
Concept
Numeric functions do arithmetic the operators cannot express. The important ones are about rounding, because that is where money quietly goes missing.
Syntax
| Function | Does | Example | Result |
|---|---|---|---|
ROUND(n, d) | round to d decimals | ROUND(1234.567, 2) | 1234.57 |
FLOOR(n) | largest integer <= n | FLOOR(-1.2) | -2 |
CEILING(n) | smallest integer >= n | CEILING(1.2) | 2 |
TRUNCATE(n, d) | cut, do not round | TRUNCATE(1.789, 1) | 1.7 |
ABS(n) | absolute value | ABS(-40) | 40 |
MOD(a, b) or a % b | remainder | MOD(17, 5) | 2 |
POWER(a, b) | exponent | POWER(2, 10) | 1024 |
GREATEST / LEAST | max / min across arguments | GREATEST(3, 9, 4) | 9 |
Example
SELECT first_name,
salary,
ROUND(salary / 12, 2) AS monthly,
ROUND(salary * 0.18, 0) AS tax_estimate,
FLOOR(salary / 10000) AS salary_band,
MOD(id, 2) AS id_parity
FROM employees
ORDER BY salary DESC;Explanation
FLOOR(salary / 10000) is a neat way to bucket a continuous value into bands without a long CASE. MOD(id, 2) splits rows into two even groups - useful for sampling and for A/B style reporting.
Integer division
-- MySQL and MariaDB return a decimal
SELECT 7 / 2; -- 3.5000
SELECT 7 DIV 2; -- 3, explicit integer division
-- PostgreSQL, SQL Server and Oracle truncate when both sides are integers
-- SELECT 7 / 2; -- 3
-- SELECT 7 * 1.0 / 2; -- 3.5Rounding is not one rule
SELECT ROUND(2.5), ROUND(3.5), ROUND(-2.5);Most engines round halves away from zero here (3, 4, -3), but some numeric types and some products use banker's rounding (round half to even), giving 2, 4, -2. If a total must reconcile to the penny, never assume - test on the exact engine, and do the final rounding in one agreed place.
Important rules
- Rounding a
FLOATcan still surprise you, because the stored value was never exactly what you typed. RoundDECIMALvalues. - Division by zero raises an error in PostgreSQL, SQL Server and Oracle. MySQL and MariaDB return
NULLby default, and error only in strict mode. NULLin,NULLout - for every one of these functions.ROUND(n, d)with a negativedrounds to tens, hundreds and so on:ROUND(1234, -2)is 1200.
Common mistakes
- Rounding at every intermediate step and accumulating drift. Round once, at the end.
- Using
FLOORwhereROUNDwas meant, and losing a rupee per row. - Assuming
FLOOR(-1.2)is -1. It is -2;FLOORmoves toward negative infinity,TRUNCATEmoves toward zero. - Dividing by a column that can be zero without guarding it with
NULLIF(divisor, 0).
Best practices
- Use
DECIMALfor money and round exactly once, as late as possible. - Guard every division:
total / NULLIF(quantity, 0)returnsNULLinstead of erroring. - Agree one rounding rule across the application, the database and the reporting tool.
- Keep raw values stored; compute derived values in the query or a view.
Practice
- Return each order's total and the total rounded to the nearest hundred.
- Compute the average unit price per order item, guarding against a zero quantity.
- What do
FLOOR(-2.5),CEILING(-2.5)andTRUNCATE(-2.5, 0)each return, and why are they all different?