WITH Clause
The WITH clause is an optional clause that precedes the body of the SELECT statement, and defines one or more CTEs (common table expressions) that can be referenced later in the statement.
Syntax
Basic CTE
[ WITH
    cte_name1 [ ( cte_column_list ) ] AS ( SELECT ... )
  [ , cte_name2 [ ( cte_column_list ) ] AS ( SELECT ... ) ]
  [ , cte_nameN [ ( cte_column_list ) ] AS ( SELECT ... ) ]
]
SELECT ...
Recursive CTE
[ WITH [ RECURSIVE ]
    cte_name1 ( cte_column_list ) AS ( anchorClause UNION ALL recursiveClause )
  [ , cte_name2 ( cte_column_list ) AS ( anchorClause UNION ALL recursiveClause ) ]
  [ , cte_nameN ( cte_column_list ) AS ( anchorClause UNION ALL recursiveClause ) ]
]
SELECT ...
Where:
- anchorClause:- SELECT anchor_column_list FROM ...
- recursiveClause:- SELECT recursive_column_list FROM ... [ JOIN ... ]
Parameters
| Parameter | Description | 
|---|---|
| cte_name | The CTE name must follow standard identifier rules | 
| cte_column_list | The names of the columns in the CTE | 
| anchor_column_list | The columns used in the anchor clause for the recursive CTE | 
| recursive_column_list | The columns used in the recursive clause for the recursive CTE | 
Examples
Basic CTE
WITH high_value_customers AS (
    SELECT customer_id, customer_name, total_spent
    FROM customers 
    WHERE total_spent > 10000
)
SELECT c.customer_name, o.order_date, o.order_amount
FROM high_value_customers c
JOIN orders o ON c.customer_id = o.customer_id
ORDER BY o.order_date DESC;
Multiple CTEs
WITH
  regional_sales AS (
    SELECT region, SUM(sales_amount) as total_sales
    FROM sales_data
    GROUP BY region
  ),
  top_regions AS (
    SELECT region, total_sales
    FROM regional_sales
    WHERE total_sales > 1000000
  )
SELECT r.region, r.total_sales
FROM top_regions r
ORDER BY r.total_sales DESC;
Recursive CTE
WITH RECURSIVE countdown AS (
    -- Anchor clause: starting point
    SELECT 10 as num
    
    UNION ALL
    
    -- Recursive clause: repeat until condition
    SELECT num - 1
    FROM countdown 
    WHERE num > 1  -- Stop condition
)
SELECT num FROM countdown 
ORDER BY num DESC;
Usage Notes
- CTEs are temporary named result sets that exist only for the duration of the query
- CTE names must be unique within the same WITH clause
- A CTE can reference previously defined CTEs in the same WITH clause
- Recursive CTEs require both an anchor clause and a recursive clause connected by UNION ALL
- The RECURSIVE keyword is required when using recursive CTEs