Example 1
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.
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);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;| bucket | students |
|---|---|
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 2 |
Only PostgreSQL supports WIDTH_BUCKET natively. MySQL, MariaDB, SQL Server, and SQLite require arithmetic expressions to replicate the bucketing logic.