sqlcmd.net validated sql reference
advanced math PostgreSQL

Bin Numeric Values Into Equal-Width Buckets With WIDTH_BUCKET

Use `WIDTH_BUCKET(value, low, high, n)` to assign each row to one of `n` equal-width buckets between `low` and `high` — the foundation for building numeric histograms directly in SQL.

Docker-validated Not currently validation-green

Count how many students fall into each score range

WIDTH_BUCKET(score, 40, 100, 4) divides the range [40, 100) into 4 equal buckets of width 15: bucket 1 is [40, 55), bucket 2 is [55, 70), bucket 3 is [70, 85), bucket 4 is [85, 100). Frank's score of 45 lands in bucket 1 (one student). Alice (55) and Dave (63) land in bucket 2 (two students). Bob (72), Grace (78), and Hal (82) land in bucket 3 (three students). Carol (88) and Eve (91) land in bucket 4 (two students). Grouping by the bucket result and counting gives the frequency distribution. Values below 40 would return 0 and values 100 or above would return 5, acting as underflow and overflow buckets — the data here has none. To display bucket labels rather than numbers, wrap the result in a CASE expression or join against a buckets table that maps numbers to label strings.

Rows loaded before the example query runs.
Setup
CREATE TABLE students (name VARCHAR(20), score INT);

INSERT INTO
  students
VALUES
  ('Alice', 55),
  ('Bob', 72),
  ('Carol', 88),
  ('Dave', 63),
  ('Eve', 91),
  ('Frank', 45),
  ('Grace', 78),
  ('Hal', 82);
Shared across supported engines.
SQL
SELECT
  WIDTH_BUCKET(score, 40, 100, 4) AS bucket,
  COUNT(*) AS students
FROM
  students
GROUP BY
  WIDTH_BUCKET(score, 40, 100, 4)
ORDER BY
  bucket;
Returned rows for the shared example.
bucketstudents
11
22
33
42

Only PostgreSQL supports WIDTH_BUCKET natively. MySQL, MariaDB, SQL Server, and SQLite require arithmetic expressions to replicate the bucketing logic.

Where this command helps.

  • building a score distribution histogram to see how many students fall into each grade range
  • bucketing a continuous metric like response time into fixed bands for a bar chart

What the command is doing.

WIDTH_BUCKET(value, low, high, n) divides the half-open range [low, high) into n equal-width intervals and returns the bucket number (1 through n) that value falls into. Values below low return 0; values at or above high return n + 1. The bucket width is (high − low) / n. To build a frequency histogram, call WIDTH_BUCKET in a SELECT, then GROUP BY the result and count rows per bucket. PostgreSQL supports WIDTH_BUCKET natively. SQL Server, MySQL, and MariaDB do not provide this function; the equivalent is GREATEST(1, LEAST(n, FLOOR((value - low) * n / (high - low)) + 1)). SQLite also lacks WIDTH_BUCKET but the same arithmetic expression works. WIDTH_BUCKET is also available in Oracle and is defined in the SQL:2003 standard.