Supported OpenSearch SQL commands and functions - Amazon OpenSearch Service

Supported OpenSearch SQL commands and functions

The following reference tables show which SQL commands are supported in OpenSearch Discover for querying data in Amazon S3, Security Lake, or CloudWatch Logs, and which SQL commands are supported in CloudWatch Logs Insights. The SQL syntax supported in CloudWatch Logs Insights and that supported in OpenSearch Discover for querying CloudWatch Logs are the same, and referenced as CloudWatch Logs in the following tables.

Note

OpenSearch also has SQL support for querying data that is ingested in OpenSearch and stored in indexes. This SQL dialect is different than the SQL used in direct query and is referred to as OpenSearch SQL on indexes.

Commands

Note

In the example commands column, replace <tableName/logGroup> as needed depending on which data source you're querying.

  • Example command: SELECT Body , Operation FROM <tableName/logGroup>

  • If you're querying Amazon S3 or Security Lake, use: SELECT Body , Operation FROM table_name

  • If you're querying CloudWatch Logs, use: SELECT Body , Operation FROM `LogGroupA`

Command Description CloudWatch Logs Amazon S3 Security Lake Example command

SELECT clause

Displays projected values.

Supported Supported Supported
SELECT method, status FROM <tableName/logGroup>
WHERE clause

Filters log events based on the provided field criteria.

Supported Supported Supported
SELECT * FROM <tableName/logGroup> WHERE status = 100
GROUP BY clause

Groups log events based on category and finds the average based on stats.

Supported Supported Supported
SELECT method, status, COUNT(*) AS request_count, SUM(bytes) AS total_bytes FROM <tableName/logGroup> GROUP BY method, status
HAVING clause

Filters the results based on grouping conditions.

Supported Supported Supported
SELECT method, status, COUNT(*) AS request_count, SUM(bytes) AS total_bytes FROM <tableName/logGroup> GROUP BY method, status HAVING COUNT(*) > 5
ORDER BY clause

Orders the results based on fields in the order clause. You can sort in either descending or ascending order.

Supported Supported Supported
SELECT * FROM <tableName/logGroup> ORDER BY status DESC

JOIN clause

( INNER | CROSS | LEFT OUTER )

Joins the results for two tables based on common fields.

Supported (must use Inner and Left Outer keywords for join; Only only one JOIN operation is supported in a SELECT statement)

Supported (must use Inner, Left Outer, and Cross keywords for join) Supported (must use Inner, Left Outer, and Cross keywords for join)
SELECT A.Body, B.Timestamp FROM <tableNameA/logGroupA> AS A INNER JOIN <tableNameB/logGroupB> AS B ON A.`requestId` = B.`requestId`
LIMIT clause

Restricts the results to first N rows.

Supported Supported Supported
SELECT * FROM <tableName/logGroup> LIMIT 10
CASE clause Evaluates conditions and returns a value when the first condition is met. Supported Supported Supported
SELECT method, status, CASE WHEN status BETWEEN 100 AND 199 THEN 'Informational' WHEN status BETWEEN 200 AND 299 THEN 'Success' WHEN status BETWEEN 300 AND 399 THEN 'Redirection' WHEN status BETWEEN 400 AND 499 THEN 'Client Error' WHEN status BETWEEN 500 AND 599 THEN 'Server Error' ELSE 'Unknown Status' END AS status_category, CASE method WHEN 'GET' THEN 'Read Operation' WHEN 'POST' THEN 'Create Operation' WHEN 'PUT' THEN 'Update Operation' WHEN 'PATCH' THEN 'Partial Update Operation' WHEN 'DELETE' THEN 'Delete Operation' ELSE 'Other Operation' END AS operation_type, bytes, datetime FROM <tableName/logGroup>
Common table expression Creates a named temporary result set within a SELECT, INSERT, UPDATE, DELETE, or MERGE statement. Not supported Supported Supported
WITH RequestStats AS ( SELECT method, status, bytes, COUNT(*) AS request_count FROM tableName GROUP BY method, status, bytes ) SELECT method, status, bytes, request_count FROM RequestStats WHERE bytes > 1000
EXPLAIN Displays the execution plan of a SQL statement without actually executing it. Not supported Supported Supported
EXPLAIN SELECT k, SUM(v) FROM VALUES (1, 2), (1, 3) AS t(k, v) GROUP BY k
LATERAL SUBQUERY clause Allows a subquery in the FROM clause to reference columns from preceding items in the same FROM clause. Not supported Supported Supported
SELECT * FROM tableName LATERAL ( SELECT * FROM t2 WHERE t1.c1 = t2.c1 )
LATERAL VIEW clause Generates a virtual table by applying a table-generating function to each row of a base table. Not supported Supported Supported
SELECT * FROM tableName LATERAL VIEW EXPLODE(ARRAY(30, 60)) tableName AS c_age LATERAL VIEW EXPLODE(ARRAY(40, 80)) AS d_age
LIKE predicate Matches a string against a pattern using wildcard characters. Supported Supported Supported
SELECT method, status, request, host FROM <tableName/logGroup> WHERE method LIKE 'D%'
OFFSET Specifies the number of rows to skip before starting to return rows from the query. Supported when used in conjunction with a LIMIT clause in a query. For example:
  • Supported: SELECT * FROM Table LIMIT 100 OFFSET 10

  • Not supported: SELECT * FROM Table OFFSET 10

Supported Supported
SELECT method, status, bytes, datetime FROM <tableName/logGroup> ORDER BY datetime OFFSET 10
PIVOT clause Transforms rows into columns, rotating data from a row-based format to a column-based format. Not supported Supported Supported
SELECT * FROM ( SELECT method, status, bytes FROM <tableName/logGroup> ) AS SourceTable PIVOT ( SUM(bytes) FOR method IN ('GET', 'POST', 'PATCH', 'PUT', 'DELETE') ) AS PivotTable
Set operators Combines the results of two or more SELECT statements (e.g., UNION, INTERSECT, EXCEPT). Supported Supported Supported
SELECT method, status, bytes FROM <tableName/logGroup> WHERE status = '416' UNION SELECT method, status, bytes FROM <tableName/logGroup> WHERE bytes > 20000
SORT BY clause Specifies the order in which to return the query results. Supported Supported Supported
SELECT method, status, bytes FROM <tableName/logGroup> SORT BY bytes DESC
UNPIVOT Transforms columns into rows, rotating data from a column-based format to a row-based format. Not supported Supported Supported
SELECT status, REPLACE(method, '_bytes', '') AS request_method, bytes, datetime FROM PivotedData UNPIVOT ( bytes FOR method IN ( GET_bytes, POST_bytes, PATCH_bytes, PUT_bytes, DELETE_bytes ) ) AS UnpivotedData

Functions

Note

In the example commands column, replace <tableName/logGroup> as needed depending on which data source you're querying.

  • Example command: SELECT Body , Operation FROM <tableName/logGroup>

  • If you're querying Amazon S3 or Security Lake, use: SELECT Body , Operation FROM table_name

  • If you're querying CloudWatch Logs, use: SELECT Body , Operation FROM `LogGroupA`

Available SQL Grammar Description CloudWatch Logs Amazon S3 Security Lake Example command
String functions

Built-in functions that can manipulate and transform string and text data within SQL queries. For example, converting case, combining strings, extracting parts, and cleaning text.

Supported Supported Supported
SELECT UPPER(method) AS upper_method, LOWER(host) AS lower_host FROM <tableName/logGroup>
Date and time functions

Built-in functions for handling and transforming date and timestamp data in queries. For example, date_add, date_format, datediff, and current_date.

Supported Supported Supported
SELECT TO_TIMESTAMP(datetime) AS timestamp, TIMESTAMP_SECONDS(UNIX_TIMESTAMP(datetime)) AS from_seconds, UNIX_TIMESTAMP(datetime) AS to_unix, FROM_UTC_TIMESTAMP(datetime, 'PST') AS to_pst, TO_UTC_TIMESTAMP(datetime, 'EST') AS from_est FROM <tableName/logGroup>
Aggregate functions

Built-in functions that perform calculations on multiple rows to produce a single summarized value. For example, sum, count, avg, max, and min.

Supported

Supported

Supported
SELECT COUNT(*) AS total_records, COUNT(DISTINCT method) AS unique_methods, SUM(bytes) AS total_bytes, AVG(bytes) AS avg_bytes, MIN(bytes) AS min_bytes, MAX(bytes) AS max_bytes FROM <tableName/logGroup>
Conditional functions

Built-in functions that perform actions based on specified conditions, or that evaluate expressions conditionally. For example, CASE and IF.

Supported Supported Supported
SELECT CASE WHEN method = 'GET' AND bytes < 1000 THEN 'Small Read' WHEN method = 'POST' AND bytes > 10000 THEN 'Large Write' WHEN status >= 400 OR bytes = 0 THEN 'Problem' ELSE 'Normal' END AS request_type FROM <tableName/logGroup>
JSON functions

Built-in functions for parsing, extracting, modifying, and querying JSON-formatted data within SQL queries (e.g., from_json, to_json, get_json_object, json_tuple) allowing manipulation of JSON structures in datasets.

Supported Supported Supported
SELECT FROM_JSON( @message, 'STRUCT< host: STRING, user-identifier: STRING, datetime: STRING, method: STRING, status: INT, bytes: INT >' ) AS parsed_json FROM <tableName/logGroup>
Array functions

Built-in functions for working with array-type columns in SQL queries, allowing operations like accessing, modifying, and analyzing array data (e.g., size, explode, array_contains).

Supported Supported Supported
SELECT scores, size(scores) AS length, array_contains(scores, 90) AS has_90 FROM <tableName/logGroup>
Window functions Built-in functions that perform calculations across a specified set of rows related to the current row (window), enabling operations like ranking, running totals, and moving averages (e.g., ROW_NUMBER, RANK, LAG, LEAD) Supported

Supported
Supported
SELECT field1, field2, RANK() OVER (ORDER BY field2 DESC) AS field2Rank FROM <tableName/logGroup>
Conversion functions

Built-in functions for converting data from one type to another within SQL queries, enabling data type transformations and format conversions (e.g., CAST, TO_DATE, TO_TIMESTAMP, BINARY)

Supported Supported Supported
SELECT CAST('123' AS INT) AS converted_number, CAST(123 AS STRING) AS converted_string FROM <tableName/logGroup>
Predicate functions

Built-in functions that evaluate conditions and return boolean values (true/false) based on specified criteria or patterns (e.g., IN, LIKE, BETWEEN, IS NULL, EXISTS)

Supported Supported Supported
SELECT * FROM <tableName/logGroup> WHERE id BETWEEN 50000 AND 75000
Map functions Applies a specified function to each element in a collection, transforming the data into a new set of values. Not supported Supported Supported
SELECT MAP_FILTER( MAP( 'method', method, 'status', CAST(status AS STRING), 'bytes', CAST(bytes AS STRING) ), (k, v) -> k IN ('method', 'status') AND v != 'null' ) AS filtered_map FROM <tableName/logGroup> WHERE status = 100
Mathematical functions Performs mathematical operations on numeric data, such as calculating averages, sums, or trigonometric values. Supported Supported Supported
SELECT bytes, bytes + 1000 AS added, bytes - 1000 AS subtracted, bytes * 2 AS doubled, bytes / 1024 AS kilobytes, bytes % 1000 AS remainder FROM <tableName/logGroup>
Multi-log group functions

Enables users to specify multiple log groups in a SQL SELECT statement

Supported Not applicable Not applicable
SELECT lg1.Column1, lg1.Column2 FROM `logGroups(logGroupIdentifier: ['LogGroup1', 'LogGroup2'])` AS lg1 WHERE lg1.Column3 = "Success"
Generator functions Creates an iterator object that yields a sequence of values, allowing for efficient memory usage in large data sets. Not supported Supported Supported
SELECT explode(array(10, 20))

General SQL restrictions

The following restrictions apply when using OpenSearch SQL with CloudWatch Logs, Amazon S3, and Security Lake.

  1. You can only use one JOIN operation in a SELECT statement.

  2. Only one level of nested subqueries is supported.

  3. Multiple statement queries separated by semi-colons aren't supported.

  4. Queries containing field names that are identical but differ only in case (such as field1 and FIELD1) are not supported.

    For example, the following queries are not supported:

    Select AWSAccountId, awsaccountid from LogGroup

    However, the following query is because the field name (@logStream) is identical in both log groups:

    Select a.`@logStream`, b.`@logStream` from Table A INNER Join Table B on a.id = b.id
  5. Functions and expressions must operate on field names and be part of a SELECT statement with a log group specified in the FROM clause.

    For example, this query is not supported:

    SELECT cos(10) FROM LogGroup

    This query is supported:

    SELECT cos(field1) FROM LogGroup

Additional information for CloudWatch Logs Insights users using OpenSearch SQL

If you're a CloudWatch Logs user, you can use OpenSearch SQL in the Logs Insights console, API or CLI. Most of the OpenSearch SQL commands such as SELECT, FROM, WHERE, GROUP BY, HAVING, JOINS, and nested queries are supported, including JSON, mathematics, string, conditional, and other functions. However, some commands and functions which aren't supported when querying CloudWatch Logs. For example, queries involving DDL and DML statements aren't supported because CloudWatch Logs only allows read operations. For a detailed list of query commands and functions supported in CloudWatch Logs, see the CloudWatch Logs columns in the above tables.

Multi-log group functions

CloudWatch Logs Insights supports the ability to query multiple log groups. To address this use case in SQL, you can use the logGroups command. This command is specific to querying data in CloudWatch Logs Insights involving one or more log groups. Using this syntax, you can query multiple log groups easily by specifying them in the command, instead of writing a query for each of the log groups and combining them with a UNION command.

Syntax:

`logGroups( logGroupIdentifier: ['LogGroup1','LogGroup2', ...'LogGroupn'] )

In this syntax, you can specify up to 50 log groups in the logGroupIndentifier parameter. To reference log groups in a monitoring account, use ARNs instead of LogGroup names.

Example query:

SELECT LG1.Column1, LG1.Column2 from `logGroups( logGroupIdentifier: ['LogGroup1', 'LogGroup2'] )` as LG1 WHERE LG1.Column1 = 'ABC'

The following syntax involving multiple log groups after the FROM statement is not supported when querying CloudWatch Logs:

SELECT Column1, Column2 FROM 'LogGroup1', 'LogGroup2', ...'LogGroupn' WHERE Column1 = 'ABC'

Restrictions

When using SQL or PPL commands, enclose certain fields in backticks to successfully query them. Backticks are needed for fields with special characters (non-alphabetic and non-numeric). For example, enclose @message, Operation.Export, and Test::Field in backticks. You don't need to enclose columns with purely alphabetic names in backticks.

Example query with simple fields:

SELECT SessionToken, Operation, StartTime FROM `LogGroup-A` LIMIT 1000;

Same query with backticks appended:

SELECT `SessionToken`, `Operation`, `StartTime` FROM `LogGroup-A` LIMIT 1000;

For additional general restrictions that aren't specific to CloudWatch Logs, see General SQL restrictions.

Sample queries and quotas

Note

The following applies to both CloudWatch Logs Insights users and OpenSearch users querying CloudWatch data.

For sample SQL queries that you can use in CloudWatch Logs, see Saved and sample queries in the Amazon CloudWatch Logs Insights console for examples.

For information about the limits that apply when querying CloudWatch Logs from OpenSearch Service, see CloudWatch Logs quotas in the Amazon CloudWatch Logs User Guide. Limits involve the number of CloudWatch Log groups you can query, the maximum concurrent queries that you can execute, the maximum query execution time, and the maximum number of rows returned in results. The limits are the same regardless of which language you use for querying CloudWatch Logs (namely, OpenSearch PPL, SQL, and Logs Insights).