# Multi-statement queries > Several statements in one tab, separated by semicolons, run as one BigQuery script, with variables, temp tables, and a result for every statement. Querylab.io estimates the script before it runs. Source: https://docs.querylab.io/writing-sql/multi-statement-queries/ **Query 1 · 4.8 GB | ~$0.03** ```sql DECLARE threshold INT64 DEFAULT 100; CREATE TEMP TABLE active_users AS SELECT user_id, email, login_count FROM `ace-analytics.warehouse.users` WHERE login_count > threshold; SELECT country, COUNT(\*) AS users FROM active_users a JOIN `ace-analytics.warehouse.user_profiles` p USING (user_id) GROUP BY country ORDER BY users DESC; DROP TABLE IF EXISTS active_users; ``` estimated per statement ## Running a script `⌘` `Enter` (`Ctrl` `Enter` on Windows and Linux) or **Run Query** sends the whole tab to BigQuery as a script. BigQuery runs the statements in order, each as a child job; an error stops the script at the statement that failed, and the statements before it stay applied. To run one statement, select it and press `⌘ Enter`: only the selection runs. The gutter diamonds do the same per statement, and price it first: see [Partial execution](https://docs.querylab.io/writing-sql/partial-execution/). ## Cancelling a run While a query or script runs, **Run Query** at the right of the status bar turns into **Cancel**. Hover it to see "Cancel query". **status bar** Left: a query is running. Right: Cancel was clicked and BigQuery has been asked to stop the job. Clicking it sends a cancel request for the job to BigQuery and the button changes to **Canceling...** and is disabled until the job ends. The run then ends with the message "Query execution was cancelled by user". BigQuery can still bill for the work the job did before it stopped. ## Reading results per statement When the script has more than one visible statement, a bar above the results lists them. Each entry is the statement's number and the start of its SQL, with a green check or a red error icon once it's done. **results**
CREATE ( Temporary table 'daily_orders' is created but never dropped) with a quick fix, `⌘` `.` → Add DROP TABLE IF EXISTS daily_orders, that appends the statement at the end of the script.{" "} DROP TABLE _SESSION.daily_orders counts as dropped too.
[SQL Notebooks](https://docs.querylab.io/notebooks/) avoid the problem: each cell's result lands in an anonymous table that Querylab.io cleans up. A notebook's ⋮ menu has **Copy SQL as CTEs** and **Copy SQL as temp tables** for turning it back into a single script.
## Completions across statements
- After its `CREATE`, a temp table appears in `FROM` and `JOIN` completions as a **Temporary Table**, and `alias.` lists its columns, inferred from the `AS SELECT` or from the column list, including `STRUCT` fields.
- Before its `CREATE`, it doesn't.
- After a semicolon, the list starts with statement keywords: `SELECT`, `CREATE`, `DECLARE`, `INSERT`, …
- `@@` lists BigQuery's system variables (`@@project_id`, `@@row_count`, …) and the `@@script.` members with their types.
```sql
CREATE TEMP TABLE metrics AS
SELECT user_id, COUNT(*) AS total, AVG(amount) AS avg_amount
FROM `ace-analytics.warehouse.orders` GROUP BY user_id;
SELECT metrics. FROM metrics
```
## Declaring variables
`DECLARE` and `SET` work as in BigQuery, with any type:
```sql
DECLARE start_date DATE DEFAULT '2024-01-01';
DECLARE end_date DATE DEFAULT CURRENT_DATE();
DECLARE total INT64;
DECLARE tags ARRAY