Skip to main content
This guide covers the fundamentals of querying data with NQL: selecting columns, filtering rows with WHERE clauses, and transforming data using expressions and functions.

Prerequisites

  • A Narrative I/O account with at least one dataset
  • Basic familiarity with SQL syntax

What you’ll learn

  • How to select specific columns and use aliases
  • How to filter data with comparison and logical operators
  • How to transform data using expressions and functions
  • How to work with complex types (arrays, structs, maps)

Selecting columns

Basic column selection

Select specific columns from a dataset:

Using column aliases

Rename columns in your output with AS:

Fully qualified column names

When joining datasets or for clarity, use fully qualified names:
Always use fully qualified column names in joins to avoid ambiguity.
NQL requires explicit column lists. Wildcards (SELECT *) are not supported. See Explicit Column Selection for why and how to list columns explicitly.

Select distinct values

Remove duplicates with DISTINCT:

Filtering with WHERE

Comparison filters

Filter rows using comparison operators:

Combining conditions

Use AND, OR, and NOT to combine conditions:
Use parentheses to control evaluation order. AND is evaluated before OR.

IN and NOT IN

Check membership in a list:

BETWEEN

Filter within a range (inclusive):

NULL checks

Check for missing values:
Don’t use = NULL or <> NULL. These always return NULL, not true/false. Use IS NULL and IS NOT NULL.

Pattern matching with LIKE

Match string patterns using LIKE wildcards:
For case-insensitive matching, normalize the case first:

Date and time filtering

Current date comparisons

Filter relative to the current date:

Date ranges

Filter within specific date ranges:

Extracting date parts

Filter by specific date components:

Price filtering

Control costs by filtering on the special _price_cpm_usd column:
Always include price filtering to control data acquisition costs, especially when creating materialized views.

Transforming data

Expressions in SELECT

Compute values using expressions:

CASE expressions

Apply conditional logic:

String transformations

Clean and format text:

Type casting

Convert between types:

Working with complex types

Accessing array elements

Use bracket notation with zero-based indexing:

Accessing struct fields

Use dot notation:

Nested access

Combine notation for deeply nested data:

Accessing map values

Use ELEMENT_AT for maps:

Expanding arrays with UNNEST

Convert array elements to rows:
This creates one row per array element. If a user has tags ['a', 'b', 'c'], the result includes three rows for that user.

Aggregating data

Basic aggregations

Compute summary statistics:

Grouping

Aggregate by categories:

Filtering aggregated results

Use HAVING to filter after aggregation:

Deduplication with QUALIFY

Remove duplicates based on a window function:
This keeps only the most recent record for each user.

Putting it together

Here’s a complete example combining multiple techniques:

Joining Datasets

Combine data from multiple sources

NQL Syntax Reference

Complete syntax documentation

Operators Reference

All comparison and logical operators

Functions Reference

String, date, and transformation functions