Docs
DocumentationQuery ReferenceAPI Reference
Open Console→→
DocumentationQuery ReferenceAPI Reference

Introduction

Query reference overview

APL

IntroductionSample queriesAll features
Functions
Scalar functions
Array functions
Overview
array_concat
array_extract
array_iff
array_index_of
array_length
array_reverse
array_rotate_left
array_rotate_right
array_select_dict
array_shift_left
array_shift_right
array_slice
array_sort_asc
array_sort_desc
array_split
array_sum
bag_has_key
bag_keys
bag_pack
bag_zip
isarray
len
pack_array
pack_dictionary
strcat_array
Conditional functions
Overview
case
iff
Conversion functions
Overview
dynamic_to_json
ensure_field
isbool
toarray
tobool
todatetime
todouble, toreal
todynamic
tohex
toint, tolong
tostring
totimespan
Datetime functions
Overview
ago
datetime_add
datetime_diff
datetime_part
dayofmonth
dayofweek
dayofyear
endofday
endofmonth
endofweek
endofyear
getmonth
getyear
hourofday
monthofyear
now
startofday
startofmonth
startofweek
startofyear
unixtime_microseconds_todatetime
unixtime_milliseconds_todatetime
unixtime_nanoseconds_todatetime
unixtime_seconds_todatetime
week_of_year
GenAI functions
Overview
genai_concat_contents
genai_conversation_turns
genai_cost
genai_estimate_tokens
genai_extract_assistant_response
genai_extract_function_results
genai_extract_system_prompt
genai_extract_tool_calls
genai_extract_user_prompt
genai_get_content_by_index
genai_get_content_by_role
genai_get_pricing
genai_get_role
genai_has_tool_calls
genai_input_cost
genai_is_truncated
genai_message_roles
genai_output_cost
Hash functions
Overview
hash
hash_md5
hash_sha1
hash_sha256
hash_sha512
IP functions
Overview
format_ipv4
format_ipv4_mask
geo_info_from_ip_address
has_any_ipv4
has_any_ipv4_prefix
has_ipv4
has_ipv4_prefix
ipv4_compare
ipv4_is_in_range
ipv4_is_in_any_range
ipv4_is_match
ipv4_is_private
ipv4_netmask_suffix
ipv6_compare
ipv6_is_in_any_range
ipv6_is_in_range
ipv6_is_match
parse_ipv4
parse_ipv4_mask
Mathematical functions
Overview
abs
acos
asin
atan
atan2
cos
cot
degrees
exp
exp2
exp10
gamma
isfinite
isinf
isint
isnan
log
log2
log10
loggamma
max_of
min_of
not
pi
pow
radians
rand
range
round
set_difference
set_has_element
set_intersect
set_union
sign
sin
sqrt
tan
Metadata functions
Overview
column_ifexists
cursor_current
ingestion_time
Pair functions
Overview
find_pair
pair
parse_pair
Rounding functions
Overview
bin
bin_auto
ceiling
floor
String functions
Overview
base64_decode_toarray
base64_decode_tostring
base64_encode_fromarray
base64_encode_tostring
coalesce
countof
countof_regex
extract
extract_all
format_bytes
format_url
gettype
indexof
indexof_regex
isascii
isempty
isnotempty
isnotnull
isnull
parse_bytes
parse_csv
parse_json
parse_path
parse_url
parse_urlquery
quote
regex_quote
replace
replace_regex
replace_string
reverse
split
strcat
strcat_delim
strcmp
string_size
strlen
strrep
strip_ansi_escapes
substring
tolower
totitle
toupper
translate
trim
trim_end
trim_end_regex
trim_regex
trim_space
trim_start
trim_start_regex
unicode_codepoints_from_string
unicode_codepoints_to_string
url_decode
url_encode
SQL functions
Overview
parse_sql
format_sql
Time series functions
Overview
series_abs
series_acos
series_add
series_asin
series_atan
series_ceiling
series_cos
series_cosine_similarity
series_divide
series_dot_product
series_equals
series_exp
series_fft
series_fill_backward
series_fill_const
series_fill_forward
series_fill_linear
series_fir
series_floor
series_greater
series_greater_equals
series_ifft
series_iir
series_less
series_less_equals
series_log
series_magnitude
series_max
series_min
series_multiply
series_not_equals
series_pearson_correlation
series_pow
series_sign
series_sin
series_stats
series_stats_dynamic
series_subtract
series_sum
series_tan
Type functions
Overview
isimei
ismap
isreal
iscc
isstring
isutf8
Aggregation functions
Overview
arg_min
arg_max
avg
avgif
count
countif
dcount
dcountif
histogram
histogramif
make_list
make_list_if
make_set
make_set_if
max
maxif
min
minif
percentile
percentileif
percentiles_array
percentiles_arrayif
phrases
rate
spotlight
stdev
stdevif
sum
sumif
topk
topkif
variance
varianceif
Operators
Tabular operators
Overview
count
distinct
extend
extend-valid
externaldata
getschema
join
limit
lookup
make-series
mv-expand
order
parse
parse-kv
parse-where
project
project-away
project-keep
project-rename
project-reorder
redact
sample
search
sort
summarize
take
top
union
where
Scalar operators
Set membership operators
Overview
in
!in
in~
!in~
Logical
Numerical
String
Reference
Entity names
Map fields
Null values
Scalar data types
Set statement
Special field attributes
Migrate
Splunk SPL
SQL
Sumo Logic

MPL

Language featuresHistograms and summariesSample queriesMigrate
APL/Operators

join

This page explains how to use the join operator in APL.

The join operator in Axiom Processing Language (APL) combines rows from two datasets based on matching values in specified columns. Use join to correlate data from different sources or datasets, such as linking logs to traces or enriching logs with additional metadata.

This operator is useful when you want to:

  • Combine information from two datasets with shared keys.
  • Analyze relationships between different types of events.
  • Enrich existing data with supplementary details.
Info

The join operator is currently in public preview. For more information, see Feature states.

The preview of the join operator works with variable limits depending on the structure of your dataset. For the left side of the join, the limit is 50,000 rows when the dataset has fewer than 100 fields. This limit decreases linearly as the field count increases. For example, the limit is 25,000 rows when your dataset has 200 fields, 12,500 rows at 400 fields, and 10,000 rows at more than 500 fields. The right side of the join has a consistent limit of 50,000 rows.

You can’t use the join operator in dashboard queries. To combine data from multiple datasets in a dashboard, rewrite your query without using joins or use alternative approaches such as virtual fields or pre-aggregated data.

Kinds of join

The kinds of join and their typical use cases are the following:

  • inner (default): Returns rows where the join conditions exist in both datasets. All matching rows from the right dataset are included for each matching row in the left dataset. Useful to retain all matches without limiting duplicates.
  • innerunique: Matches rows from both datasets where the join conditions exist in both. For each row in the left dataset, only the first matching row from the right dataset is returned. Optimized for performance when duplicate matching rows on the right dataset are irrelevant.
  • leftouter: Returns all rows from the left dataset. If a match exists in the right dataset, the matching rows are included; otherwise, columns from the right dataset are null. Retains all data from the left dataset, enriching it with matching data from the right dataset.
  • rightouter: Returns all rows from the right dataset. If a match exists in the left dataset, the matching rows are included; otherwise, columns from the left dataset are null. Retains all data from the right dataset, enriching it with matching data from the left dataset.
  • fullouter: Returns all rows from both datasets. Matching rows are combined, while non-matching rows from either dataset are padded with null values. Combines both datasets while retaining unmatched rows from both sides.
  • leftanti: Returns rows from the left dataset that have no matches in the right dataset. Identifies rows in the left dataset that don’t have corresponding entries in the right dataset.
  • rightanti: Returns rows from the right dataset that have no matches in the left dataset. Identifies rows in the right dataset that don’t have corresponding entries in the left dataset.
  • leftsemi: Returns rows from the left dataset that have at least one match in the right dataset. Only columns from the left dataset are included. Filters rows in the left dataset based on existence in the right dataset.
  • rightsemi: Returns rows from the right dataset that have at least one match in the left dataset. Only columns from the right dataset are included. Filters rows in the right dataset based on existence in the left dataset.
Info

The preview of the join operator currently only supports the following types of join:

  • inner
  • innerunique
  • leftouter

Summary of kinds of join

Kind of joinBehaviorMatches returned
innerAll matches between left and right datasetsMultiple matches allowed
inneruniqueFirst match for each row in the left datasetOnly unique matches
leftouterAll rows from the left, with matching rows from the right or nullLeft-dominant
rightouterAll rows from the right, with matching rows from the left or nullRight-dominant
fullouterAll rows from both datasets, with unmatched rows padded with nullComplete join
leftantiRows in the left dataset with no matches in the right datasetNo matches
rightantiRows in the right dataset with no matches in the left datasetNo matches
leftsemiRows in the left dataset with at least one match in the right datasetMatching rows (left dataset only)
rightsemiRows in the right dataset with at least one match in the left datasetMatching rows (right dataset only)

Choose the right kind of join

  • Use inner for standard joins where you need all matches.
  • Use leftouter or rightouter when you need to retain all rows from one dataset.
  • Use leftanti or rightanti to find rows that don’t match.
  • Use fullouter for complete combinations of both datasets.
  • Use leftsemi or rightsemi to filter rows based on existence in another dataset.

Usage

Syntax

APL
LeftDataset
| join kind=KindOfJoin RightDataset on Conditions

Parameters

  • LeftDataset: The first dataset, also known as the outer dataset or the left side of the join. If you expect one of the datasets to contain consistently less data than the other, specify the smaller dataset as the left side of the join.
  • RightDataset: The second dataset, also known as the inner dataset or the right side of the join.
  • KindOfJoin: Optionally, the kind of join to perform.
  • Conditions: The conditions for matching rows. The conditions are equality expressions that determine how Axiom matches rows from the LeftDataset (left side of the equality expression) with rows from the RightDataset (right side of the equality expression). The two sides of the equality expression must have the same data type.
    • To join datasets on a field that has the same name in the two datasets, simply use the field name. For example, on id.
    • To join datasets on a field that has different names in the two datasets, define the two field names in an equality expression such as on id == trace_id.
    • You can use expressions in the join conditions. For example, to compare two fields of different data types, use on id_string == tostring(trace_id_int).
    • You can define multiple join conditions. To separate conditions, use commas (,). Don’t use and. For example, on id == trace_id, span == span_id.

Returns

The join operator returns a new table containing rows that match the specified join condition. The fields from the left and right datasets are included.

Use case example

Join HTTP logs with trace data to correlate user activity with performance metrics.

Query

APL
['otel-demo-traces']
| join kind=inner ['otel-demo-logs'] on trace_id

Output

_timetrace_idspan_idservice.nameduration
2024-12-01trace123span123frontend500ms

This query links user activity in HTTP logs to trace data to investigate performance issues.

List of related operators

  • union: Combines rows from multiple datasets without requiring a matching condition.
  • where: Filters rows based on conditions, often used with join for more precise results.

Other query languages

Was this page helpful?
Suggest edits on GitHub
PreviousgetschemaNextlimit
On this page
Kinds of joinSummary of kinds of joinChoose the right kind of joinUsageSyntaxParametersReturnsUse case exampleList of related operatorsOther query languages