sqlpostgresqlmysqlclickhouse

CEIL y CEILING en SQL: redondear hacia arriba al entero

Como CEIL/CEILING redondea hacia arriba, calcula paginas de paginacion y crea buckets, y en que se diferencia de FLOOR y ROUND.

2 min de lecturaReferencesql · postgresql · mysql · clickhouse · math · pagination

CEIL (tambien escrito CEILING) redondea un numero hacia arriba al entero mas cercano que no sea menor que el valor de entrada. Es la herramienta basica para contar paginas de paginacion, agrupar datos en buckets y cualquier logica del tipo "cuantos contenedores necesito para guardar N elementos".

Comportamiento basico

CEIL siempre avanza hacia el infinito positivo. Los enteros se quedan igual; cualquier parte decimal empuja el resultado hacia arriba.

SELECT
  CEIL(4.1)  AS a,   -- 5
  CEIL(4.0)  AS b,   -- 4
  CEIL(-4.1) AS c,   -- -4  (toward zero, not away)
  CEILING(7.0001) AS d; -- 8

Puntos clave:

  • CEIL y CEILING son sinonimos exactos en todas las bases de datos importantes.
  • Para numeros negativos, "arriba" significa hacia el cero: CEIL(-4.1) es -4, no -5.
  • En PostgreSQL el resultado sobre numeric sigue siendo numeric, y sobre double precision sigue siendo double precision. La parte decimal siempre se descarta.

Contar paginas de paginacion

El caso clasico: tienes total filas y per_page por pagina, asi que cuantas paginas hay? La division entera trunca el resto, por eso necesitas CEIL.

SELECT
  COUNT(*) AS total_orders,
  CEIL(COUNT(*)::numeric / 25) AS total_pages
FROM orders
WHERE status = 'paid';

El mismo truco por pais, para saber cuantas pantallas de lista hacen falta para mostrar a todos los usuarios a 20 por pagina:

SELECT
  country,
  COUNT(*) AS users,
  CEIL(COUNT(*)::numeric / 20) AS pages
FROM users
GROUP BY country
ORDER BY users DESC;

Trampa: la division entera. En PostgreSQL 5 / 2 es 2 (entero), y CEIL(5 / 2) devuelve 2, no 3. La division ya ocurrio antes de ejecutar CEIL. Convierte siempre al menos un operando a un tipo decimal: CEIL(5::numeric / 2) o CEIL(5.0 / 2).

Buckets y agrupacion por rangos

CEIL es excelente para asignar valores continuos a buckets discretos de ancho fijo. Agrupa empleados en bandas salariales de ancho 10000:

SELECT
  CEIL(salary / 10000.0) * 10000 AS salary_band,
  COUNT(*) AS people
FROM employees
GROUP BY CEIL(salary / 10000.0)
ORDER BY salary_band;

Un empleado que gana 41000 cae en la banda 50000 (el borde superior del rango de 40001 a 50000). Si quieres el borde inferior, usa FLOOR. Puedes cortar los importes de los pedidos en segmentos de precio de la misma forma:

SELECT
  CEIL(amount / 100.0) AS price_bucket,
  COUNT(*) AS orders
FROM orders
GROUP BY CEIL(amount / 100.0)
ORDER BY price_bucket;

CEIL frente a FLOOR y ROUND

Tres funciones, tres direcciones distintas:

  • CEIL(x) redondea hacia arriba, al infinito positivo: CEIL(2.1) = 3, CEIL(2.9) = 3.
  • FLOOR(x) redondea hacia abajo, al infinito negativo: FLOOR(2.9) = 2, FLOOR(-2.1) = -3.
  • ROUND(x) redondea al entero mas cercano: ROUND(2.4) = 2, ROUND(2.5) = 3.
SELECT
  x,
  CEIL(x)  AS up,
  FLOOR(x) AS down,
  ROUND(x) AS nearest
FROM (VALUES (2.1), (2.5), (2.9), (-2.5)) AS t(x);

Para la paginacion y los calculos de "cuantos contenedores", usa solo CEIL: incluso una sola fila extra necesita otra pagina completa, y ROUND se equivocaria justo en el punto medio.

Diferencias entre bases de datos

  • PostgreSQL y MySQL: CEIL y CEILING se comportan igual; en MySQL tambien cuidado con la division entera, usa / con literales decimales o un cast.
  • ClickHouse: la funcion es ceil y acepta un segundo argumento de precision: ceil(4.123, 1) es 4.2. Resulta util para redondear hacia arriba a decimas o centesimas, algo que el CEIL estandar no puede hacer.
  • En todos los sistemas CEIL(NULL) devuelve NULL, asi que tenlo en cuenta en agregados y COALESCE.
-- ClickHouse: round up to one decimal place
SELECT ceil(4.123, 1) AS r;  -- 4.2

Practica con ejercicios reales

Resuelve ejercicios en el entrenador de SQL con corrección instantánea y pistas.

Abrir el entrenador