[discrete] [[esql-auto_bucket]] === `AUTO_BUCKET` *Syntax* [source,esql] ---- AUTO_BUCKET(expression, buckets, from, to) ---- *Parameters* `field`:: Numeric or date expression from which to derive buckets. `buckets`:: Target number of buckets. `from`:: Start of the range. Can be a number or a date expressed as a string. `to`:: End of the range. Can be a number or a date expressed as a string. *Description* Creates human-friendly buckets and returns a value for each row that corresponds to the resulting bucket the row falls into. Using a target number of buckets, a start of a range, and an end of a range, `AUTO_BUCKET` picks an appropriate bucket size to generate the target number of buckets or fewer. For example, asking for at most 20 buckets over a year results in monthly buckets: [source.merge.styled,esql] ---- include::{esql-specs}/date.csv-spec[tag=docsAutoBucketMonth] ---- [%header.monospaced.styled,format=dsv,separator=|] |=== include::{esql-specs}/date.csv-spec[tag=docsAutoBucketMonth-result] |=== The goal isn't to provide *exactly* the target number of buckets, it's to pick a range that people are comfortable with that provides at most the target number of buckets. Combine `AUTO_BUCKET` with <> to create a histogram: [source.merge.styled,esql] ---- include::{esql-specs}/date.csv-spec[tag=docsAutoBucketMonthlyHistogram] ---- [%header.monospaced.styled,format=dsv,separator=|] |=== include::{esql-specs}/date.csv-spec[tag=docsAutoBucketMonthlyHistogram-result] |=== NOTE: `AUTO_BUCKET` does not create buckets that don't match any documents. That's why this example is missing `1985-03-01` and other dates. Asking for more buckets can result in a smaller range. For example, asking for at most 100 buckets in a year results in weekly buckets: [source.merge.styled,esql] ---- include::{esql-specs}/date.csv-spec[tag=docsAutoBucketWeeklyHistogram] ---- [%header.monospaced.styled,format=dsv,separator=|] |=== include::{esql-specs}/date.csv-spec[tag=docsAutoBucketWeeklyHistogram-result] |=== NOTE: `AUTO_BUCKET` does not filter any rows. It only uses the provided range to pick a good bucket size. For rows with a value outside of the range, it returns a bucket value that corresponds to a bucket outside the range. Combine `AUTO_BUCKET` with <> to filter rows. `AUTO_BUCKET` can also operate on numeric fields. For example, to create a salary histogram: [source.merge.styled,esql] ---- include::{esql-specs}/ints.csv-spec[tag=docsAutoBucketNumeric] ---- [%header.monospaced.styled,format=dsv,separator=|] |=== include::{esql-specs}/ints.csv-spec[tag=docsAutoBucketNumeric-result] |=== Unlike the earlier example that intentionally filters on a date range, you rarely want to filter on a numeric range. You have to find the `min` and `max` separately. {esql} doesn't yet have an easy way to do that automatically. *Examples* Create hourly buckets for the last 24 hours, and calculate the number of events per hour: [source.styled,esql] ---- include::{esql-specs}/date.csv-spec[tag=docsAutoBucketLast24hr] ---- Create monthly buckets for the year 1985, and calculate the average salary by hiring month: [source.merge.styled,esql] ---- include::{esql-specs}/date.csv-spec[tag=auto_bucket_in_agg] ---- [%header.monospaced.styled,format=dsv,separator=|] |=== include::{esql-specs}/date.csv-spec[tag=auto_bucket_in_agg-result] |===