On this page
Syntax
FLOOR(number)FLOOR(column)FLOOR(expression) | Parameter | Type | Required | Description |
|---|---|---|---|
number |
numeric | yes | Any numeric value or expression. FLOOR returns the greatest integer that is not greater than this value. |
How it works
FLOOR() takes a number and returns the largest whole number that is less than or equal to it. It always rounds down: FLOOR(2.1), FLOOR(2.5) and FLOOR(2.9) all return 2. It is the mirror image of CEIL(), which rounds up.
The important detail is what "down" means for negative numbers. FLOOR rounds toward negative infinity, not toward zero. So FLOOR(-1.2) is -2, because -2 is the largest integer that is still less than or equal to -1.2. This is different from truncation, which simply drops the fractional part and moves toward zero. See TRUNCATE() for that behaviour.
A very common use of FLOOR() is bucketing continuous values into fixed ranges. Dividing, flooring and multiplying back, as in FLOOR(age / 10) * 10, snaps every value down to the start of its band, which groups ages into decades, prices into brackets, and timestamps into intervals. It is available in every major dialect: MySQL, PostgreSQL, SQL Server and SQLite. For rounding to the nearest integer rather than always down, use CEIL() or the standard ROUND function.
Examples
Round a value down to whole units
-- 4 boxes hold 10 items each; how many full boxes?
SELECT FLOOR(47 / 10.0) AS full_boxes;
full_boxes
----------
4Bucket ages into decades
-- snap every age down to the start of its decade
SELECT name, age,
FLOOR(age / 10) * 10 AS age_band
FROM customers
ORDER BY age;
name | age | age_band ------+-----+--------- Sara | 19 | 10 Omar | 27 | 20 Lina | 34 | 30 Ali | 41 | 40
FLOOR with a negative number
-- FLOOR rounds toward negative infinity, not toward zero
SELECT FLOOR(-1.2) AS a,
FLOOR(-0.1) AS b,
FLOOR( 2.9) AS c;
a | b | c ----+----+--- -2 | -1 | 2
FLOOR versus casting to an integer
-- CAST truncates toward zero; FLOOR rounds down.
-- They disagree on negative values.
SELECT FLOOR(-3.7) AS floor_val,
CAST(-3.7 AS INT) AS cast_val;
floor_val | cast_val
----------+---------
-4 | -3Common mistakes
-- Expecting FLOOR to drop the fraction (truncate).
-- For -1.9 this returns -2, not -1.
SELECT FLOOR(-1.9); -- -2
Right
-- Use TRUNCATE (or CAST to int) to move toward zero
SELECT TRUNCATE(-1.9, 0); -- -1
The most common FLOOR() mistake: assuming it truncates toward zero. FLOOR always rounds toward negative infinity, so FLOOR(-1.9) is -2. If you want to just drop the decimals, use TRUNCATE() instead.
-- Using FLOOR when you meant "nearest"
-- FLOOR(2.8) is 2, losing the near round-up
SELECT FLOOR(2.8) AS score; -- 2
Right
-- ROUND goes to the nearest integer
SELECT ROUND(2.8) AS score; -- 3
Do not confuse FLOOR with ROUND. FLOOR always goes down, so FLOOR(2.8) is 2. ROUND returns the nearest integer, so ROUND(2.8) is 3. Pick FLOOR only when you specifically want the value rounded down.
Performance
FLOOR() is a cheap scalar operation applied per row, so it has almost no cost on its own. The performance trap is wrapping an indexed column in FLOOR() inside a WHERE clause, as in WHERE FLOOR(price) = 10. That makes the predicate non-sargable: the database must compute FLOOR for every row and cannot use an index on price.
When you need to filter on a floored value, rewrite the condition as a range on the raw column, for example WHERE price >= 10 AND price < 11, which lets the optimiser use an index range scan. Reserve FLOOR for the SELECT list and for GROUP BY bucketing, where it runs once per output row rather than blocking an index.
Interview questions
What does FLOOR() do, and how is it different from CEIL()?
FLOOR() returns the largest integer less than or equal to the input, so it always rounds down. CEIL() returns the smallest integer greater than or equal to the input, so it always rounds up. For example FLOOR(2.4) is 2 while CEIL(2.4) is 3.
What is FLOOR(-1.2), and why?
It is -2. FLOOR rounds toward negative infinity, and -2 is the largest integer that is still less than or equal to -1.2. It does not round toward zero, so it is not -1.
How is FLOOR different from truncating or casting to an integer?
Truncation (and a plain CAST to int) drops the fractional part and moves toward zero, so both give -3 for -3.7. FLOOR moves toward negative infinity, giving -4 for -3.7. They agree on positive numbers but differ on negatives. Use TRUNCATE() when you want the toward-zero behaviour.
SELECT FLOOR(-3.7) AS floor_val,
TRUNCATE(-3.7, 0) AS trunc_val;
How would you group a continuous column into fixed-size buckets?
Divide by the bucket size, floor the result, then multiply back. For decades that is FLOOR(age / 10) * 10, which snaps each value down to the start of its band. The same pattern works for price brackets and time intervals.
SELECT FLOOR(age / 10) * 10 AS age_band,
COUNT(*) AS customers
FROM customers
GROUP BY FLOOR(age / 10) * 10
ORDER BY age_band;
Why can wrapping a column in FLOOR() slow down a query?
A predicate like WHERE FLOOR(price) = 10 is non-sargable: the database must compute FLOOR for every row and cannot use an index on price. Rewrite it as a range such as price >= 10 AND price < 11 so an index range scan can be used.