Functions Reference¶
Complete reference of ASQL built-in functions.
Aggregate Functions¶
count¶
Count rows or non-null values.
count(*) -- Count all rows
count(column) -- Count non-null values
count(distinct column) -- Count distinct values
-- -- Shorthand for count(*)
#(column) -- Shorthand for count(column)
sum¶
Sum numeric values.
sum(amount) -- Sum of amount
sum_amount -- Shorthand (same as above)
total(amount) -- Alias for sum
total amount -- Natural language style
avg / average¶
Calculate average.
avg(price) -- Average price
average(price) -- Alias
avg_price -- Shorthand
average of price -- Natural language
min / minimum¶
Find minimum value.
min(date) -- Earliest date
minimum(amount) -- Smallest amount
min_created_at -- Shorthand
max / maximum¶
Find maximum value.
max(amount) -- Largest amount
maximum(amount) -- Alias
max_created_at -- Shorthand
Date Truncation Functions¶
Truncate dates to a specific precision.
year¶
year(created_at) -- Truncate to year start: 2025-01-01
year_created_at -- Shorthand
year of created_at -- Natural language
month¶
month(created_at) -- Truncate to month start: 2025-03-01
week¶
week(created_at) -- Truncate to week start (Monday)
week_monday(created_at) -- Explicit Monday start
week_sunday(created_at) -- Sunday start
day¶
day(created_at) -- Truncate to day: 2025-03-15
hour¶
hour(created_at) -- Truncate to hour: 2025-03-15 14:00:00
quarter¶
quarter(created_at) -- Truncate to quarter start
Date Part Extraction¶
Extract specific parts from dates (returns integers).
day of week¶
day of week created_at -- 1-7 (Monday = 1)
day_of_week(created_at) -- Function style
day of month¶
day of month created_at -- 1-31
day_of_month(created_at)
day of year¶
day of year created_at -- 1-366
day_of_year(created_at)
week of year¶
week of year created_at -- 1-52
week_of_year(created_at)
month of year¶
month of year created_at -- 1-12
month_of_year(created_at)
quarter of year¶
quarter of year created_at -- 1-4
quarter_of_year(created_at)
Date Difference Functions¶
Calculate time between dates.
days¶
days(end_date - start_date) -- Integer days between
days_between(start, end) -- Alternative syntax
weeks¶
weeks(end_date - start_date) -- Integer weeks between
weeks_between(start, end)
months¶
months(end_date - start_date) -- Integer months between
months_between(start, end)
years¶
years(end_date - start_date) -- Integer years between
years_between(start, end)
hours¶
hours(end_date - start_date) -- Integer hours between
Time Since/Until Functions¶
Calculate time elapsed since a date, or time remaining until a future date.
days_since / days_until¶
-- Three equivalent syntaxes:
days_since(created_at) -- Function call (recommended)
days since created_at -- Space notation
days_since_created_at -- Underscore alias
days_until(due_date) -- Time remaining
days until due_date
days_until_due_date
weeks_since / weeks_until¶
weeks_since(signup_date)
weeks since signup_date
weeks_since_signup_date
weeks_until(deadline)
weeks until deadline
months_since / months_until¶
months_since(last_login)
months since last_login
months_until(renewal_date)
months until renewal_date
years_since / years_until¶
years_since(birth_date) -- Calculate age
years since birth_date
years_until(contract_end)
hours_since / hours_until¶
hours_since(event_time)
hours since event_time
minutes_since / minutes_until¶
minutes_since(last_update)
minutes since last_update
seconds_since / seconds_until¶
seconds_since(request_time)
seconds since request_time
Window Functions¶
prior¶
Access previous row value (LAG).
prior(revenue) -- Previous row's revenue
prior(revenue, 3) -- 3 rows back
next¶
Access next row value (LEAD).
next(revenue) -- Next row's revenue
next(revenue, 2) -- 2 rows ahead
running_sum¶
Cumulative sum from start.
running_sum(amount) -- Cumulative total
running sum amount -- Space style
running_avg¶
Cumulative average from start.
running_avg(amount) -- Average to date
running_count¶
Cumulative count from start.
running_count(*) -- Row number (effectively)
rolling_avg¶
Moving average with window size.
rolling_avg(price, 7) -- 7-day moving average
rolling_avg(price, 30) -- 30-day moving average
rolling_sum¶
Moving sum with window size.
rolling_sum(amount, 7) -- 7-day rolling sum
rolling_min¶
Moving minimum with window size.
rolling_min(price, 7) -- 7-day rolling minimum
rolling_max¶
Moving maximum with window size.
rolling_max(price, 7) -- 7-day rolling maximum
rolling_count¶
Moving count with window size.
rolling_count(events, 7) -- 7-day rolling count
first¶
Get first value with ordering.
first(order_id order by -order_date) -- Latest order
first(order_id order by order_date) -- Earliest order
last¶
Get last value with ordering.
last(order_id order by order_date) -- Latest order
arg_max¶
Value where another column is maximum.
arg_max(order_id, order_date) -- order_id at max order_date
arg_min¶
Value where another column is minimum.
arg_min(order_id, order_date) -- order_id at min order_date
row_number¶
Standard SQL window function.
row_number() over (partition by customer_id order by -order_date)
rank¶
Standard SQL window function.
rank() over (partition by department order by -salary)
dense_rank¶
Standard SQL window function (no gaps).
dense_rank() over (partition by category order by -revenue)
String Functions¶
concat¶
Concatenate strings.
concat(first_name, " ", last_name)
string_agg¶
Aggregate strings with separator.
string_agg(product_name, ", ")
upper / lower¶
Change case.
upper(name)
lower(email)
trim / ltrim / rtrim¶
Remove whitespace.
trim(input)
ltrim(input)
rtrim(input)
length¶
String length.
length(name)
substring¶
Extract substring.
substring(email, 1, 5)
email[1:5] -- Slice syntax
replace¶
Replace text.
replace(text, "old", "new")
slugify¶
Convert text to URL-safe slugs.
slugify(name) -- "Hello World!" → "hello-world"
slugify(title) as slug -- URL-friendly version
Converts to lowercase, replaces non-alphanumeric characters with hyphens, and trims leading/trailing hyphens.
Null Handling Functions¶
coalesce¶
Return first non-null value.
value ?? default -- Operator form (preferred)
primary_email ?? secondary_email ?? "unknown" -- Chained fallbacks
-- Function form (also accepted)
coalesce(primary_email, secondary_email, "unknown")
Type Functions¶
cast¶
Explicit type conversion.
value::INTEGER -- Cast to integer
value::DATE -- Cast to date
value::TIMESTAMP -- Cast to timestamp
value::INTEGER? -- Safe cast (NULL on failure)
Binning Functions¶
bucket¶
Discretize continuous values into labeled bins. Compiles to portable CASE WHEN expressions.
Form 1: Explicit boundaries with labels
bucket(score, [0, 60, 70, 80, 90, 100], ['F', 'D', 'C', 'B', 'A']) as grade
Creates bins:
- [0, 60) → 'F'
- [60, 70) → 'D'
- [70, 80) → 'C'
- [80, 90) → 'B'
- [90, 100] → 'A' (last bin includes upper bound)
Form 2: Explicit boundaries with auto-labels
bucket(amount, [0, 100, 500, 1000]) as tier
Auto-generates range labels: '0-100', '100-500', '500-1000'
Form 3: Width-based bins
bucket(value, start=0, end=100, width=10) as decile
Generates evenly-spaced bins: '0-10', '10-20', ..., '90-100'
Examples¶
-- Grade students by score
from students
select name, score,
bucket(score, [0, 60, 70, 80, 90, 100], ['F', 'D', 'C', 'B', 'A']) as grade
-- Segment customers by lifetime value
from customers
select *,
bucket(lifetime_value, [0, 100, 1000, 10000, 100000],
['bronze', 'silver', 'gold', 'platinum']) as tier
-- Age demographics with auto-labels
from users
group by bucket(age, [0, 18, 30, 50, 65, 100]) (
# as count
)
-- Temperature ranges (supports negative values)
from readings
select *,
bucket(temp_celsius, [-40, -20, 0, 20, 40]) as temp_category
-- Percentile-style bins
from sales
select *,
bucket(amount, start=0, end=1000, width=100) as amount_bucket
Boundary Behavior¶
- Left-inclusive: Each bin includes its lower bound
- Right-exclusive: Each bin excludes its upper bound (except the last)
- Last bin includes upper bound:
[90, 100]not[90, 100) - Out of range: Values outside boundaries return
NULL
Gap-Filling Functions¶
fill_forward¶
Propagate the last non-null value forward to fill gaps.
fill_forward(value) -- Fill NULLs with previous value
Useful for time series where missing data should inherit the previous value.
from daily_prices
order by date
select date, fill_forward(price) as price
Compiles to: LAST_VALUE(col) IGNORE NULLS OVER (ROWS UNBOUNDED PRECEDING)
fill_backward¶
Propagate the next non-null value backward to fill gaps.
fill_backward(value) -- Fill NULLs with next value
from forecasts
order by date
select date, fill_backward(target) as target
Compiles to: FIRST_VALUE(col) IGNORE NULLS OVER (ROWS CURRENT ROW TO UNBOUNDED FOLLOWING)
Special Functions¶
key¶
Generate a deterministic surrogate key from one or more columns. Inspired by dbt_utils' generate_surrogate_key.
key(user_id, order_id) as order_key
key(source, record_id) as unique_id
The function: - Concatenates column values with a separator - Handles NULLs consistently (converts to empty string) - Returns an MD5 hash of the concatenated values
-- Create stable keys for fact tables
from raw_events
select *,
key(user_id, event_type, timestamp) as event_key
-- Deduplicate by composite key
from staging_data
group by key(source_system, record_id) (
first(*)
)
guarantee (Planned)¶
Note:
guarantee()is a planned feature not yet implemented.
Specify explicit values for group by spine.
guarantee(status, ['pending', 'active', 'completed'])
Function Aliases¶
| Natural Language | SQL Function |
|---|---|
total |
SUM |
average |
AVG |
maximum |
MAX |
minimum |
MIN |
Auto-Generated Column Names¶
When functions are used without explicit AS aliases, ASQL automatically generates meaningful column names:
| Function | Auto-Alias |
|---|---|
sum(amount) |
sum_amount |
avg(price) |
avg_price |
count(*) / # |
num |
month(created_at) |
month_created_at |
upper(name) |
upper_name |
See the Auto-Aliasing Reference for the complete mapping table and configuration.
See Also¶
- Auto-Aliasing — Automatic column naming
- Operators Reference — All operators
- Aggregations — Using aggregates
- Window Functions — Window function patterns