DDSQL is SQL for Datadog data. It implements several standard SQL operations, such as SELECT, and allows queries against unstructured data. You can perform actions like getting exactly the data you want by writing your own SELECT statement, or querying tags as if they are standard table columns.
This documentation covers the SQL support available and includes:
This clause is a shorthand for joins where the join columns have the same name in both tables. It takes a comma-separated list of those columns and creates a separate equality condition for each matching pair. For example, joining T1 and T2 with USING (a, b) is equivalent to ON T1.a = T2.a AND T1.b = T2.b.
Represents a time duration specified in a given unit. Supported units: - milliseconds / millisecond - seconds / second - minutes / minute - hours / hour - days / day
Data types
DDSQL supports the following data types:
Data Type
Description
BIGINT
64-bit signed integers.
BOOLEAN
true or false values.
DOUBLE
Double-precision floating-point numbers.
INTERVAL
Time duration values.
JSON
JSON data.
TIMESTAMP
Date and time values.
VARCHAR
Variable-length character strings.
Array types
All data types support array types. Arrays can contain multiple values of the same data type.
Type literals
DDSQL supports explicit type literals using the syntax [TYPE] [value].
Type
Syntax
Example
BIGINT
BIGINT value
BIGINT 1234567
BOOLEAN
BOOLEAN value
BOOLEAN true
DOUBLE
DOUBLE value
DOUBLE 3.14159
INTERVAL
INTERVAL 'value unit'
INTERVAL '30 minutes'
JSON
JSON 'value'
JSON '{"key": "value", "count": 42}'
TIMESTAMP
TIMESTAMP 'value'
TIMESTAMP '2023-12-25 10:30:00'
VARCHAR
VARCHAR 'value'
VARCHAR 'hello world'
The type prefix can be omitted and the type is automatically inferred from the value. For example, 'hello world' is inferred as VARCHAR, 123 as BIGINT, and true as BOOLEAN. Use explicit type prefixes when values could be ambiguous; for example,TIMESTAMP '2025-01-01' would be inferred as VARCHAR without the prefix.
Array literals
Array literals use the syntax ARRAY[value1, value2, ...]. The array type is automatically inferred from the values.
SELECTARRAY['apple','banana','cherry']ASfruits;-- Inferred as VARCHAR array
SELECTARRAY[1,2,3]ASnumbers;-- Inferred as BIGINT array
SELECTARRAY[true,false,true]ASflags;-- Inferred as BOOLEAN array
SELECTARRAY[1.1,2.2,3.3]ASdecimals;-- Inferred as DOUBLE array
Example
-- Using type literals in queries
SELECTVARCHAR'Product Name: '||nameASlabeled_name,price*DOUBLE1.08ASprice_with_tax,created_at+INTERVAL'7 days'ASexpiry_dateFROMproductsWHEREcreated_at>TIMESTAMP'2025-01-01';
Functions
The following SQL functions are supported. For Window function, see the separate Window function section in this documentation.
Function
Return Type
Description
MIN(variable v)
typeof v
Returns the smallest value in a set of data.
MAX(variable v)
typeof v
Returns the maximum value across all input values.
COUNT(any a)
numeric
Returns the number of input values that are not null.
SUM(numeric n)
numeric
Returns the summation across all input values.
AVG(numeric n)
numeric
Returns the average value (arithmetic mean) across all input values.
CEIL(numeric n)
numeric
Returns the value rounded up to the nearest integer.
FLOOR(numeric n)
numeric
Returns the value rounded down to the nearest integer.
ROUND(numeric n)
numeric
Returns the value rounded to the nearest integer.
LOWER(string s)
string
Returns the string as lowercase.
UPPER(string s)
string
Returns the string as uppercase.
ABS(numeric n)
numeric
Returns the absolute value.
COALESCE(args a)
typeof first non-null a OR null
Returns the first non-null value or null if all are null.
CAST(value AS type)
type
Converts the given value to the specified data type.
LENGTH(string s)
integer
Returns the number of characters in the string.
TRIM(string s)
string
Removes leading and trailing whitespace from the string.
REPLACE(string s, string from, string to)
string
Replaces occurrences of a substring within a string with another substring.
SUBSTRING(string s, int start, int length)
string
Extracts a substring from a string, starting at a given position and for a specified length.
STRPOS(string s, string substring)
integer
Returns the first index position of the substring in a given string, or 0 if there is no match.
Splits the string on the given delimiter and returns the string at the given position counting from one.
EXTRACT(unit from timestamp/interval)
numeric
Extracts a part of a date or time field (such as year or month) from a timestamp or interval.
TO_TIMESTAMP(string timestamp, string format)
timestamp
Converts a string to a timestamp according to the given format.
TO_CHAR(timestamp t, string format)
string
Converts a timestamp to a string according to the given format.
DATE_TRUNC(string unit, timestamp t)
timestamp
Truncates a timestamp to a specified precision based on the provided unit.
CURRENT_SETTING(string setting_name)
string
Returns the current value of the specified setting. Supports the parameters dd.time_frame_start and dd.time_frame_end, which return the start and end of the global time frame, respectively.
NOW()
timestamp
Returns the current timestamp at the start of the current query.
CARDINALITY(array a)
integer
Returns the number of elements in the array.
ARRAY_POSITION(array a, typeof_array value)
integer
Returns the index of the first occurrence of the value found in the array, or null if value is not found.
STRING_TO_ARRAY(string s, string delimiter)
array of strings
Splits the given string into an array of strings using the given delimiter.
ARRAY_AGG(expression e)
array of input type
Creates an array by collecting all the input values.
UNNEST(array a [, array b...])
rows of a [, b…]
Expands arrays into a set of rows. This form is only allowed in a FROM clause.
dd.time_frame_start: Returns the start of the selected time frame in RFC 3339 format (YYYY-MM-DD HH:mm:ss.sss±HH:mm).
dd.time_frame_end: Returns the end of the selected time frame in RFC 3339 format (YYYY-MM-DD HH:mm:ss.sss±HH:mm).
-- Define the current analysis window
WITHboundsAS(SELECTCAST(CURRENT_SETTING('dd.time_frame_start')ASTIMESTAMP)AStime_frame_start,CAST(CURRENT_SETTING('dd.time_frame_end')ASTIMESTAMP)AStime_frame_end),-- Define the immediately preceding window of equal length
previous_boundsAS(SELECTtime_frame_start-(time_frame_end-time_frame_start)ASprev_time_frame_start,time_frame_startASprev_time_frame_endFROMbounds)SELECT*FROMbounds,previous_bounds
Returns substrings of the first pattern match in the string.
This function searches the input string using the given pattern and returns captured substrings (capture groups) from the first match. If no capture groups are present, returns the full match.
This table provides an overview of the supported window functions. For comprehensive details and examples, see the PostgreSQL documentation.
Function
Return Type
Description
OVER
N/A
Defines a window for a set of rows for other window functions to operate on.
PARTITION BY
N/A
Divides the result set into partitions, specifically for applying window functions.
RANK()
integer
Assigns a rank to each row within a partition, with gaps for ties.
ROW_NUMBER()
integer
Assigns a unique sequential number to each row within a partition.
LEAD(column n)
typeof column
Returns the value from the next row in the partition.
LAG(column n)
typeof column
Returns the value from the previous row in the partition.
FIRST_VALUE(column n)
typeof column
Returns the first value in an ordered set of values.
LAST_VALUE(column n)
typeof column
Returns the last value in an ordered set of values.
NTH_VALUE(column n, offset)
typeof column
Returns the value at the specified offset in an ordered set of values.
JSON functions and operators
Name
Return type
Description
json_extract_path_text(text json, text path…)
text
Extracts a JSON sub-object as text, defined by the path. Its behavior is equivalent to the Postgres function with the same name. For example, json_extract_path_text(col, ‘forest') returns the value of the key forest for each JSON object in col. See the example below for a JSON array syntax.
json_extract_path(text json, text path…)
JSON
Same functionality as json_extract_path_text, but returns a column of JSON type instead of text type.
Table functions
Join the Preview!
Querying Logs and Metrics through DDSQL is in Preview. Use this form to request access.
Returns log data as a table. The columns parameter specifies which log fields to extract, and the AS clause defines the schema of the returned table. Optional: filtering by index or time range. When time is not specified, we default to the past 1 hour of data.
Returns metric data as a scalar value. The function accepts a metrics query (with optional grouping), a reducer to determine how values are aggregated (avg, max, etc.), and optional timestamp parameters (default 1 hour) to define the time range.
SELECT*FROMdd.metric_scalar('avg:system.cpu.user{*} by {service}','avg',TIMESTAMP'2025-07-10 00:00:00.000-04:00',TIMESTAMP'2025-07-17 00:00:00.000-04:00')ORDERBYvalueDESC;
Tags
DDSQL exposes tags as an hstore type, which is inspired by PostgreSQL. You can access the values for specific tag keys using the PostgreSQL arrow operator. For example:
SELECTinstance_type,count(instance_type)FROMaws.ec2_instanceWHEREtags->'region'='us-east-1'-- region is a tag, not a column
GROUPBYinstance_type
Tags are key-value pairs where each key can have zero, one, or multiple tag values corresponding to it. When accessed, the tag value returns a single string, containing all corresponding values. When the data has multiple tag values for the same tag key, they are represented as a sorted, comma-separated string. For example: