Skip to main content
In this tutorial, you’ll write and run your first NQL query. NQL is Narrative’s query language designed for data collaboration—it lets you query your own data and shared datasets with a familiar SQL-like syntax.
This tutorial is part of the First Steps series. Complete Normalize with Rosetta Stone before starting.

Prerequisites

  • A Narrative I/O account
  • At least one normalized dataset

What you’ll learn

  • How to access the query editor
  • How to write a basic NQL query
  • How to preview results with EXPLAIN
  • How to run a query and interpret results

Steps

1

Open the query editor

From your Narrative I/O dashboard, navigate to the Query section in the left sidebar. This opens the NQL query editor where you can write and execute queries.The query editor has three main areas:
  • Editor pane: Where you write your NQL queries
  • Schema browser: Shows available datasets and their columns
  • Results pane: Displays query output after execution
2

Find your dataset ID

Before writing a query, you need your dataset’s ID. In the schema browser, expand My Datasets to see your datasets. Each dataset shows its name and numeric ID.Note the dataset ID—you’ll use it in your query. For this tutorial, we’ll use "123" as an example. Replace it with your actual dataset ID.
Dataset IDs are numeric and must be quoted in queries: company_data."123"
3

Write a SELECT query

In the editor pane, write a simple query to select data from your dataset:
SELECT
  *
FROM
  company_data."123"
LIMIT 10 ROWS
This query:
  • Selects all columns (*)
  • From your dataset (company_data."123")
  • Limits results to 10 rows
Replace "123" with your actual dataset ID.
4

Preview with EXPLAIN

Before running the query, preview what data matches your criteria using EXPLAIN:
EXPLAIN
SELECT
  *
FROM
  company_data."123"
LIMIT 10 ROWS
Click Run or press Cmd+Enter (Mac) / Ctrl+Enter (Windows).The results pane shows:
  • Estimated row count: How many rows match your query
  • Estimated cost: The data cost based on your pricing
  • Schema: The columns that will be returned
EXPLAIN doesn’t execute the query or incur costs—it only forecasts the results.
5

Run the query

Remove the EXPLAIN keyword and run your query:
SELECT
  *
FROM
  company_data."123"
LIMIT 10 ROWS
Click Run or press Cmd+Enter / Ctrl+Enter.The results pane now shows your actual data in a table format. You can:
  • Scroll through rows and columns
  • Sort by clicking column headers
  • Resize columns as needed
6

Refine your query

Now try a more specific query. Select specific columns and add a filter:
SELECT
  company_data."123".user_id,
  company_data."123".email,
  company_data."123".created_at
FROM
  company_data."123"
WHERE
  company_data."123".created_at >= CURRENT_DATE - INTERVAL '30' DAY
LIMIT 100 ROWS
This query:
  • Selects specific columns instead of all
  • Uses fully qualified column names (recommended practice)
  • Filters to records from the last 30 days
  • Returns up to 100 rows
Adjust the column names to match your dataset’s schema.
7

Export your results

To save your query results:
  1. Run your query to populate the results pane
  2. Click the Export button above the results
  3. Choose your export format (CSV, JSON, or Parquet)
  4. Download the file to your local machine
For larger result sets or recurring exports, consider creating a materialized view instead.

Understanding the query structure

Let’s break down the query you wrote:
SELECT                                    -- What columns to return
  company_data."123".user_id,
  company_data."123".email,
  company_data."123".created_at
FROM                                      -- Where to get the data
  company_data."123"
WHERE                                     -- How to filter rows
  company_data."123".created_at >= CURRENT_DATE - INTERVAL '30' DAY
LIMIT 100 ROWS                           -- How many rows to return
ClausePurpose
SELECTSpecifies which columns to include in results
FROMIdentifies the dataset(s) to query
WHEREFilters rows based on conditions
LIMITRestricts the number of rows returned

Tips for getting started

Use EXPLAIN first

Always preview queries with EXPLAIN before running them, especially for large datasets. This helps you understand data availability and estimate costs.

Start with LIMIT

Add LIMIT to your queries while exploring data. This prevents accidentally querying millions of rows.

Use fully qualified column names

When you start joining datasets, fully qualified names prevent ambiguity:
-- Fully qualified (recommended)
SELECT company_data."123".email

-- Short form (works but can be ambiguous)
SELECT email

Filter by price

Control costs by filtering on _price_cpm_usd:
WHERE company_data."123"._price_cpm_usd <= 1.00

Try these queries

Count records by category

SELECT
  company_data."123".category,
  COUNT(*) AS count
FROM
  company_data."123"
GROUP BY
  company_data."123".category
ORDER BY
  count DESC
LIMIT 20 ROWS

Find recent records

SELECT
  *
FROM
  company_data."123"
WHERE
  company_data."123".created_at >= CURRENT_DATE - INTERVAL '7' DAY
ORDER BY
  company_data."123".created_at DESC
LIMIT 50 ROWS

Check for missing data

SELECT
  COUNT(*) AS total,
  COUNT(company_data."123".email) AS has_email,
  COUNT(company_data."123".phone) AS has_phone
FROM
  company_data."123"

Next steps