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 featuresSample queriesMigrate
APL/Migrate

Migrate from SQL to APL

This guide helps you migrate SQL to APL, helping you understand key differences and providing you with query examples.

Introduction

As data grows exponentially, organizations are continuously seeking more efficient and powerful tools to manage and analyze their data. The Query tab, which utilizes the Axiom Processing Language (APL), is one such service that offers fast, scalable, and interactive data exploration capabilities.

This tutorial helps you migrate SQL to APL, helping you understand key differences and providing you with query examples.

Introduction to Axiom Processing Language (APL)

Axiom Processing Language (APL) is the language used by the Query tab, a fast and highly scalable data exploration service. APL is optimized for real-time and historical data analytics, making it a suitable choice for various data analysis tasks.

Tabular operators: In APL, there are several tabular operators that help you manipulate and filter data, similar to SQL’s SELECT, FROM, WHERE, GROUP BY, and ORDER BY clauses. Some of the commonly used tabular operators are:

  • extend: Adds new columns to the result set.
  • project: Selects specific columns from the result set.
  • where: Filters rows based on a condition.
  • summarize: Groups and aggregates data similar to the GROUP BY clause in SQL.
  • sort: Sorts the result set based on one or more columns, similar to ORDER BY in SQL.

Key differences between SQL and APL

While SQL and APL are query languages, there are some key differences to consider:

  • APL is designed for querying large volumes of structured, semi-structured, and unstructured data.
  • APL is a pipe-based language, meaning you can chain multiple operations using the pipe operator (|) to create a data transformation flow.
  • APL doesn’t use SELECT, and FROM clauses like SQL. Instead, it uses keywords such as summarize, extend, where, and project.
  • APL is case-sensitive, whereas SQL isn’t.

Benefits of migrating from SQL to APL:

  • Time Series Analysis: APL is particularly strong when it comes to analyzing time-series data (logs, telemetry data, etc.). It has a rich set of operators designed specifically for such scenarios, making it much easier to handle time-based analysis.

  • Pipelining: APL uses a pipelining model, much like the UNIX command line. You can chain commands together using the pipe (|) symbol, with each command operating on the results of the previous command. This makes it very easy to write complex queries.

  • Easy to Learn: APL is designed to be simple and easy to learn, especially for those already familiar with SQL. It doesn’t require any knowledge of database schemas or the need to specify joins.

  • Scalability: APL is a more scalable platform than SQL. This means that it can handle larger amounts of data.

  • Flexibility: APL is a more flexible platform than SQL. This means that it can be used to analyze different types of data.

  • Features: APL offers more features and capabilities than SQL. This includes features such as real-time analytics, and time-based analysis.

Basic APL Syntax

A basic APL query follows this structure:

APL
| <DatasetName>
| <FilteringOperation> 
| <ProjectionOperation> 
| <AggregationOperation>

Query Examples

Let’s see some examples of how to convert SQL queries to APL.

SELECT with a simple filter

SQL:

SQL
SELECT *
FROM [Sample-http-logs]
WHERE method = 'GET';

APL:

APLRun in Playground
['sample-http-logs']
| where method == 'GET'

COUNT with GROUP BY

SQL:

SQL
SELECT Country, COUNT(*)
FROM [Sample-http-logs]
GROUP BY method;

APL:

APLRun in Playground
['sample-http-logs']
| summarize count() by method

Top N results

SQL:

SQL
SELECT TOP 10 Status, Method
FROM [Sample-http-logs]
ORDER BY Method DESC;

APL:

APLRun in Playground
['sample-http-logs']
| top 10 by method desc
| project status, method

Simple filtering and projection

SQL:

SQL
SELECT method, status, geo.country
FROM [Sample-http-logs]
WHERE resp_header_size_bytes >= 18;

APL:

APLRun in Playground
['sample-http-logs']
| where resp_header_size_bytes >= 18
| project method, status, ['geo.country']

COUNT with a HAVING clause

SQL:

SQL
SELECT geo.country
FROM [Sample-http-logs]
GROUP BY geo.country
HAVING COUNT(*) > 100;

APL:

APLRun in Playground
['sample-http-logs']
| summarize count() by ['geo.country']
| where count_ > 100

Multiple Aggregations

SQL:

SQL
SELECT geo.country,
       COUNT(*) AS TotalRequests,
       AVG(req_duration_ms) AS AverageRequest,
       MIN(req_duration_ms) AS MinRequest,
       MAX(req_duration_ms) AS MaxRequest
FROM [Sample-http-logs]
GROUP BY geo.country;

APL:

APLRun in Playground
Users
| summarize TotalRequests = count(),
            AverageRequest = avg(req_duration_ms),
            MinRequest = min(req_duration_ms),
            MaxRequest = max(req_duration_ms) by ['geo.country']

Sum of a column

SQL:

SQL
SELECT SUM(resp_body_size_bytes) AS TotalBytes
FROM  [Sample-http-logs];

APL:

APLRun in Playground
[‘sample-http-logs’]
| summarize TotalBytes = sum(resp_body_size_bytes)

Average of a column

SQL:

SQL
SELECT AVG(req_duration_ms) AS AverageRequest
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| summarize AverageRequest = avg(req_duration_ms)

Minimum and Maximum Values of a column

SQL:

SQL
SELECT MIN(req_duration_ms) AS MinRequest, MAX(req_duration_ms) AS MaxRequest
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| summarize MinRequest = min(req_duration_ms), MaxRequest = max(req_duration_ms)

Count distinct values

SQL:

SQL
SELECT COUNT(DISTINCT method) AS UniqueMethods
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| summarize UniqueMethods = dcount(method)

Standard deviation of a data

SQL:

SQL
SELECT STDDEV(req_duration_ms) AS StdDevRequest
FROM  [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| summarize StdDevRequest = stdev(req_duration_ms)

Variance of a data

SQL:

SQL
SELECT VAR(req_duration_ms) AS VarRequest
FROM  [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| summarize VarRequest = variance(req_duration_ms)

Multiple aggregation functions

SQL:

SQL
SELECT COUNT(*) AS TotalDuration, SUM(req_duration_ms) AS TotalDuration, AVG(Price) AS AverageDuration
FROM  [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| summarize TotalOrders = count(), TotalDuration = sum( req_duration_ms), AverageDuration = avg(req_duration_ms)

Aggregation with GROUP BY and ORDER BY

SQL:

SQL
SELECT status, COUNT(*) AS TotalStatus, SUM(resp_header_size_bytes) AS TotalRequest
FROM [Sample-http-logs];
GROUP BY status
ORDER BY TotalSpent DESC;

APL:

APLRun in Playground
['sample-http-logs']
| summarize TotalStatus = count(), TotalRequest = sum(resp_header_size_bytes) by status
| order by TotalRequest desc

Count with a condition

SQL:

SQL
SELECT COUNT(*) AS HighContentStatus
FROM  [Sample-http-logs];
WHERE resp_header_size_bytes  > 1;

APL:

APLRun in Playground
['sample-http-logs']
| where resp_header_size_bytes > 1
| summarize HighContentStatus = count()

Aggregation with HAVING

SQL:

SQL
SELECT Status
FROM [Sample-http-logs];
GROUP BY Status
HAVING COUNT(*) > 10;

APL:

APLRun in Playground
['sample-http-logs']
| summarize OrderCount = count() by status
| where OrderCount > 10

Count occurrences of a value in a field

SQL:

SQL
SELECT content_type, COUNT(*) AS RequestCount
FROM  [Sample-http-logs];
WHERE content_type = ‘text/csv’;

APL:

APLRun in Playground
 ['sample-http-logs'];
| where content_type == 'text/csv'
| summarize RequestCount = count()

String Functions:

Length of a string

SQL:

SQL
SELECT LEN(Status) AS NameLength
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| extend NameLength = strlen(status)

Concatentation

SQL:

SQL
SELECT CONCAT(content_type, ' ', method) AS FullLength
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| extend FullLength = strcat(content_type, ' ', method)

Substring

SQL:

SQL
SELECT SUBSTRING(content_type, 1, 10) AS ShortDescription
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| extend ShortDescription = substring(content_type, 0, 10)

Left and Right

SQL:

SQL
SELECT LEFT(content_type, 3) AS LeftTitle, RIGHT(content_type, 3) AS RightTitle
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| extend LeftTitle = substring(content_type, 0, 3), RightTitle = substring(content_type, strlen(content_type) - 3, 3)

Replace

SQL:

SQL
SELECT REPLACE(StaTUS, 'old', 'new') AS UpdatedStatus
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| extend UpdatedStatus = replace('old', 'new', status)

Upper and Lower

SQL:

SQL
SELECT UPPER(FirstName) AS UpperFirstName, LOWER(LastName) AS LowerLastName
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| project upperFirstName = toupper(content_type), LowerLastNmae = tolower(status)

LTrim and RTrim

SQL:

SQL
SELECT LTRIM(content_type) AS LeftTrimmedFirstName, RTRIM(content_type) AS RightTrimmedLastName
FROM  [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| extend LeftTrimmedFirstName = trim_start(' ', content_type), RightTrimmedLastName = trim_end(' ', content_type)

Trim

SQL:

SQL
SELECT TRIM(content_type) AS TrimmedFirstName
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| extend TrimmedFirstName = trim(' ', content_type)

Reverse

SQL:

SQL
SELECT REVERSE(Method) AS ReversedFirstName
FROM [Sample-http-logs];

APL:

APLRun in Playground
['sample-http-logs']
| extend ReversedFirstName = reverse(method)

Case-insensitive search

SQL:

SQL
SELECT Status, Method
FROM “Sample-http-logs”
WHERE LOWER(Method) LIKE 'get’';

APL:

APLRun in Playground
['sample-http-logs']
| where tolower(method) contains 'GET'
| project status, method

Take the First Step Today: Dive into APL

The journey from SQL to APL might seem daunting at first, but with the right approach, it can become an empowering transition. It’s about expanding your data query capabilities to leverage the advanced, versatile, and fast querying infrastructure that APL provides. In the end, the goal is to enable you to draw more value from your data, make faster decisions, and ultimately propel your business forward.

Try converting some of your existing SQL queries to APL and observe the performance difference. Explore the Axiom Processing Language and start experimenting with its unique features.

Happy querying.

Was this page helpful?
Suggest edits on GitHub
PreviousMigrate from Splunk SPL to APLNextMigrate from Sumo Logic Query Language to APL
On this page
IntroductionIntroduction to Axiom Processing Language (APL)Key differences between SQL and APLBenefits of migrating from SQL to APL:Basic APL SyntaxQuery ExamplesSELECT with a simple filterCOUNT with GROUP BYTop N resultsSimple filtering and projectionCOUNT with a HAVING clauseMultiple AggregationsSum of a columnAverage of a columnMinimum and Maximum Values of a columnCount distinct valuesStandard deviation of a dataVariance of a dataMultiple aggregation functionsAggregation with GROUP BY and ORDER BYCount with a conditionAggregation with HAVINGCount occurrences of a value in a fieldString Functions:Length of a stringConcatentationSubstringLeft and RightReplaceUpper and LowerLTrim and RTrimTrimReverseCase-insensitive searchTake the First Step Today: Dive into APL