WITH clause in BigQuery

The WITH clause in BigQuery, also known as a Common Table Expression (CTE), allows us to define a temporary result set that can be referenced within a single SQL statement.

CTEs help make complex queries more readable, modular, and maintainable by breaking them into logical steps.

SQL Syntax

WITH cte_name AS (
    -- SQL query
)
SELECT column1, column2
FROM cte_name;    

Defining Multiple CTEs

We can also define multiple CTEs by separating them with commas:

SQL

WITH cte1 AS (
    SELECT ...
),
cte2 AS (
    SELECT ...
)
SELECT ...
FROM cte1
JOIN cte2 ON ...;    

Key Notes

Example: Create the Employees table.

SQL

CREATE TABLE `ashishcoder.Coding_Dataset.employees` (
  employee_id INT64,
  name STRING,
  age INT64,
  salary INT64,
  department STRING,
  gender STRING
);    

Load the data into the Employees table.

SQL

INSERT INTO `ashishcoder.Coding_Dataset.employees` VALUES
(1, 'Ashish', 24, 25000, 'Electrical', 'M'),
(2, 'Kirshan', 32, 30000, 'Electrical', 'M'),
(3, 'Anjali', 20, 25000, 'Electronics', 'F'),
(4, 'Manjulika', 30, 15000, 'Electrical', 'F'),
(5, 'Katrina', 37, 18000, 'Computer', 'F'),
(6, 'Esha', 37, 20000, 'Computer', 'F'),
(7, 'Ankita', 20, 9000, 'Electronics', 'M'),
(8, 'Meenakshi', 30, 15000, 'Computer', 'F'),
(9, 'Alia', 37, 16000, 'Electronics', 'F');    

To see the data in the Employees table, execute the following query:

SQL

SELECT *
FROM `ashishcoder.Coding_Dataset.employees`;    

The above query returns the following result:

WITH clause in BigQuery

By using the WITH clause, we define a temporary result set and then use it in the following SELECT query.

SQL

WITH MyQuery AS (
  SELECT EmployeeID,
         Name,
         Age,
         LENGTH(Name) AS NameLength
  FROM `ashishcoder.Coding_Dataset.employees`
)
SELECT EmployeeID, Name, NameLength
FROM MyQuery;    

The above query returns the following result:

WITH clause in BigQuery

Why use WITH (CTEs)?

Example: Find employees with the highest salary in each department.

SQL

WITH DepartmentMaxSalaries AS (
  SELECT
    department,
    MAX(salary) AS max_salary
  FROM `ashishcoder.Coding_Dataset.employees`
  GROUP BY department
)
SELECT e.*
FROM `ashishcoder.Coding_Dataset.employees` e
JOIN DepartmentMaxSalaries d
  ON e.department = d.department
 AND e.salary = d.max_salary;    

The above query returns the following result:

WITH clause in BigQuery

Placement Rules for WITH Clause

SQL

-- Correct
WITH cte AS (
  SELECT * FROM table
)
SELECT * FROM cte;

-- Incorrect
SELECT * FROM table
WITH cte AS (...); -- This will cause a syntax error