Docs
Docs /SQL Notebooks /Notebooks
SQL NotebooksNotebooks

SQL notebooks

A tab made of cells instead of one editor. Each SQL cell runs on its own and its result becomes a table the cells below can query by name — so a long analysis becomes a chain of small, checkable steps instead of a 200-line WITH.

[1] SQL · vehicle_data
1234
SELECT make, COUNT(*) AS vehicle_count
FROM `ace-analytics.warehouse.vehicles`
WHERE first_registered >= '2020-01-01'
GROUP BY make
[2] SQL · make_summary
12345
-- Aggregate by manufacturer using results from the vehicle_data cell
SELECT make, SUM(vehicle_count) AS total_vehicles
FROM vehicle_data
GROUP BY make
ORDER BY total_vehicles DESC
0 B | $0.00· reads the result of vehicle_data
maketotal_vehicles
1FORD4252980
2VAUXHALL2130011
3HONDA616242
4MERCEDES-BENZ305002
5RENAULT248352
5 rows

Creating one

  • E, or the caret next to New query in the sidebar → New notebook.
  • KNew SQL notebook.
  • From a query tab: the editor’s ⋯ menu → Convert to notebook. A multi-statement script becomes one cell per statement.

A new notebook has one empty SQL cell called query1.

Kinds of cells

The toolbar has Run All and three add buttons: + SQL, + Text, + Chart. The same buttons appear when you hover below the last cell.

KindWhat it is
SQLAn editor with the same completions, diagnostics and cost footer as a query tab, and a results grid underneath
TextMarkdown — click to edit, click away to render
ChartA bar, line, pie, scatter or heatmap over another cell’s result: pick Source Cell, Type, X Axis, Y Axis and an optional Group By

Every SQL and chart cell has a name, shown in its header. Click it to change it. Names start with a letter and contain only letters, digits and underscores; duplicates are refused. Cells are auto-named query1, chart1, note1, …

Cell header buttons: run, collapse, focus (opens the cell full-width; close it with the button at the top), move up, move down, a ⋯ menu with Copy to clipboard and Duplicate, and delete (with Undo). Cells can also be dragged by their handle to reorder.

Running cells

ActionHow
Run this cellThe ▶ in the cell header, or Enter in its editor
Run this cell and everything that depends on itShift-click ▶, or Enter
Run every SQL cell, top to bottomRun All — stops at the first cell that fails

Each cell runs as its own BigQuery job, with its own dry-run and its own byte limit. If any cell is over its limit, Run All asks before starting.

Referencing other cells

Write the upstream cell’s name where a table would go:

[3] SQL · dangerous_defects
1234
SELECT d.make, d.model, COUNT(*) AS defects
FROM make_summary AS m
JOIN `ace-analytics.warehouse.defects` AS d ON d.make = m.make
GROUP BY d.make, d.model

When a SELECT cell finishes, BigQuery has written its result to an anonymous table. Querylab.io remembers that table and, when a later cell runs, swaps FROM make_summary for the real reference (something like `my-project._script7f3a.anon9c1e`) before sending the job. Nothing is re-executed; the downstream cell reads the stored result.

  • The upstream cell has run in this session, or its result table still exists from a previous one — anonymous tables live about 24 hours
  • The upstream cell is a SELECT. CREATE, INSERT, MERGE, DECLARE and other statements don’t produce a result table
  • The reference is directly after FROM or JOIN

If you reference a cell that hasn’t run, the feedback bar says so before you waste a job: Cell “make_summary” has not been executed yet. Run it first. Upstream cells are never run for you.

Completions know cell names: after FROM, cells are offered like tables, and once a cell has run its result columns are offered too.

Stale cells

Edit, re-run, rename, move or delete a cell and every cell that reads from it gets a Stale marker in its header, with the reason on hover. Its old results stay visible; click the marker to re-run.

Variables

Two kinds, both flowing downward from the cell that defines them.

DECLARE variables are ordinary BigQuery scripting variables. A cell that uses one without declaring it gets the declaration prepended at run time:

[1] SQL · params
12
DECLARE start_date DATE DEFAULT '2025-09-01';
DECLARE min_tests INT64 DEFAULT 100;
[2] SQL · filtered
12345
SELECT make, COUNT(*) AS tests
FROM `ace-analytics.warehouse.mot_tests`
WHERE completed_date >= start_date
GROUP BY make
HAVING tests >= min_tests

Template variables are plain assignments in a cell of their own. A cell that contains nothing else is skipped when run — it exists only to be read.

[1] SQL · config
12
table_name = 'mot_tests';
result = 'FAILED';
[2] SQL · failed
1234
SELECT make, COUNT(*) AS failed
FROM `ace-analytics.warehouse.{{ table_name }}`
WHERE test_result = @result
GROUP BY make

{{ name }} is a text substitution, so it works for identifiers — tables, columns, project IDs. @name becomes a real query parameter (always STRING), which is what you want for values: it can’t break the SQL and BigQuery can cache the result. A missing @name fails before the job is sent, naming the variable to define.

Cost and billing per cell

The tune icon in the toolbar opens Notebook Configuration; the one in a cell header opens Cell Configuration. Both have the same fields:

cell → tune icon
Use notebook defaults
Run on Default (from Settings)
Max GB 10 GB
Max Price 0.06 $
TABLESAMPLE 1 %
Reduce costs by sampling tables (0-100)
Cell settings win over notebook settings, which win over Settings → BigQuery.

TABLESAMPLE isn’t a hidden setting: it is written into the cell’s SQL as a directive comment, so you can see and edit it. Setting it at notebook level applies it to every cell that hasn’t set its own. See TABLESAMPLE.

Getting the SQL out

The toolbar’s ⋮ menu:

  • Copy SQL as CTEs — one statement: every SELECT cell but the last becomes name AS (…) in a WITH, the last is the body. DECLARE and DDL cells go in front as-is.
  • Copy SQL as temp tables — a script: CREATE TEMP TABLE name AS (…); per cell, the last SELECT unchanged, DROP TABLE IF EXISTS lines at the end.
  • Copy to clipboard — the cells as JSON. Paste into any notebook (V with the notebook focused) to append them; a single cell’s ⋯ → Copy to clipboard does the same for one cell.

Both SQL exports show a toast with Open in new tab, which drops the generated SQL into a fresh query tab. Template-variable cells are left out; the variables aren’t substituted, so fill them in before running.

A cell’s results grid has the usual export options; the BigQuery and Cloud Storage ones add a new SQL cell with the CREATE TABLE or EXPORT DATA statement instead of opening a tab.

Share Notebook creates an encrypted link to the whole notebook — cells, text, chart configs. Billing projects and destination tables are stripped. See Sharing.