Bird
Raised Fist0
SQLquery~5 mins

Multiple CTEs in one query in SQL - Cheat Sheet & Quick Revision

Choose your learning style10 modes available
Recall & Review
beginner
What does CTE stand for in SQL?
CTE stands for Common Table Expression. It is a temporary named result set that you can reference within a SELECT, INSERT, UPDATE, or DELETE statement.
Click to reveal answer
beginner
How do you define multiple CTEs in a single SQL query?
You define multiple CTEs by separating each CTE with a comma after the WITH keyword, like this: WITH cte1 AS (...), cte2 AS (...). Then you write the main query that uses these CTEs.
Click to reveal answer
intermediate
Why use multiple CTEs instead of writing one big query?
Multiple CTEs help break down complex queries into smaller, easier-to-understand parts. Each CTE can represent a step in your data processing, making the query clearer and easier to maintain.
Click to reveal answer
intermediate
Can CTEs refer to each other in a multiple CTE query?
Yes, later CTEs can refer to earlier CTEs defined before them. This allows you to build on previous results step-by-step within the same query.
Click to reveal answer
beginner
Write a simple example of a SQL query with two CTEs.
WITH first_cte AS (SELECT 1 AS num), second_cte AS (SELECT num + 1 AS num_plus_one FROM first_cte) SELECT * FROM second_cte;
Click to reveal answer
What keyword starts the definition of multiple CTEs in a SQL query?
AWITH
BSELECT
CFROM
DJOIN
How do you separate multiple CTEs in a single WITH clause?
AUsing semicolons (;)
BUsing commas (,)
CUsing AND
DUsing OR
Can a CTE refer to another CTE defined after it in the same WITH clause?
ANo, a CTE can only refer to CTEs defined before it
BYes, order does not matter
COnly if you use RECURSIVE keyword
DOnly in MySQL
What is a main advantage of using multiple CTEs?
AThey improve query speed always
BThey allow queries without SELECT
CThey make complex queries easier to read and maintain
DThey replace indexes
Which of the following is a valid way to write multiple CTEs?
AWITH cte1 AS (...) AND cte2 AS (...) SELECT * FROM cte2;
BWITH cte1 AS (...); WITH cte2 AS (...) SELECT * FROM cte2;
CSELECT * FROM cte1; SELECT * FROM cte2;
DWITH cte1 AS (...), cte2 AS (...) SELECT * FROM cte2;
Explain how to write a SQL query with multiple CTEs and why it is useful.
Think about breaking a big problem into smaller steps.
You got /5 concepts.
    Describe the rules about referencing CTEs within multiple CTEs in one query.
    Consider the order of CTEs in the WITH clause.
    You got /4 concepts.

      Practice

      (1/5)
      1. What is the main purpose of using multiple CTEs (Common Table Expressions) in a single SQL query?
      easy
      A. To automatically create indexes on the tables used
      B. To break down complex queries into simpler, named parts for better readability
      C. To permanently store intermediate results in the database
      D. To speed up the database engine by running queries in parallel

      Solution

      1. Step 1: Understand the role of CTEs

        CTEs are temporary named result sets used inside a query to organize complex logic.
      2. Step 2: Identify the benefit of multiple CTEs

        Using multiple CTEs lets you split a big query into smaller, readable parts without permanent storage or indexing.
      3. Final Answer:

        To break down complex queries into simpler, named parts for better readability -> Option B
      4. Quick Check:

        Multiple CTEs improve query clarity = D [OK]
      Hint: Multiple CTEs split queries into named parts for clarity [OK]
      Common Mistakes:
      • Thinking CTEs create permanent tables
      • Assuming CTEs improve query speed automatically
      • Confusing CTEs with indexes
      2. Which of the following is the correct syntax to define two CTEs named cte1 and cte2 in one SQL query?
      easy
      A. WITH cte1 AS (SELECT * FROM table1), cte2 AS (SELECT * FROM table2) SELECT * FROM cte1 JOIN cte2 ON cte1.id = cte2.id;
      B. WITH cte1 AS (SELECT * FROM table1) cte2 AS (SELECT * FROM table2) SELECT * FROM cte1 JOIN cte2 ON cte1.id = cte2.id;
      C. WITH cte1 (SELECT * FROM table1); WITH cte2 (SELECT * FROM table2); SELECT * FROM cte1 JOIN cte2 ON cte1.id = cte2.id;
      D. WITH cte1 = (SELECT * FROM table1), cte2 = (SELECT * FROM table2) SELECT * FROM cte1 JOIN cte2 ON cte1.id = cte2.id;

      Solution

      1. Step 1: Recall correct CTE syntax

        Multiple CTEs are separated by commas after WITH, each defined as name AS (query).
      2. Step 2: Check each option

        WITH cte1 AS (SELECT * FROM table1), cte2 AS (SELECT * FROM table2) SELECT * FROM cte1 JOIN cte2 ON cte1.id = cte2.id; correctly uses commas and AS keyword; others miss commas or use wrong syntax.
      3. Final Answer:

        WITH cte1 AS (SELECT * FROM table1), cte2 AS (SELECT * FROM table2) SELECT * FROM cte1 JOIN cte2 ON cte1.id = cte2.id; -> Option A
      4. Quick Check:

        Multiple CTEs separated by commas = B [OK]
      Hint: Separate multiple CTEs with commas after WITH [OK]
      Common Mistakes:
      • Omitting commas between CTEs
      • Using semicolons between CTEs
      • Using equals sign instead of AS
      3. Given the following SQL query with multiple CTEs, what will be the output?
      WITH cte1 AS (SELECT 1 AS num UNION ALL SELECT 2), cte2 AS (SELECT num FROM cte1 WHERE num = 2) SELECT * FROM cte2;
      medium
      A. 1 and 2
      B. 1
      C. 2
      D. No rows returned

      Solution

      1. Step 1: Analyze cte1 content

        cte1 returns two rows with num values 1 and 2.
      2. Step 2: Analyze cte2 filtering

        cte2 selects only rows from cte1 where num = 2, so only one row with num=2.
      3. Final Answer:

        2 -> Option C
      4. Quick Check:

        cte2 filters num=2 = A [OK]
      Hint: Trace each CTE step-by-step to find final output [OK]
      Common Mistakes:
      • Assuming cte2 returns all rows from cte1
      • Confusing UNION ALL with UNION
      • Ignoring the WHERE filter in cte2
      4. Identify the error in the following SQL query using multiple CTEs:
      WITH cte1 AS (SELECT id, name FROM users) SELECT * FROM cte1; WITH cte2 AS (SELECT id FROM orders) SELECT * FROM cte2;
      medium
      A. CTEs cannot select from tables
      B. CTEs must be named with different names
      C. Missing JOIN condition between cte1 and cte2
      D. Multiple WITH clauses are not allowed in one query

      Solution

      1. Step 1: Review CTE syntax rules

        Only one WITH clause is allowed per query; multiple CTEs must be separated by commas inside one WITH.
      2. Step 2: Identify the error in the query

        The query uses two separate WITH clauses, which is invalid syntax.
      3. Final Answer:

        Multiple WITH clauses are not allowed in one query -> Option D
      4. Quick Check:

        Only one WITH clause per query = A [OK]
      Hint: Use one WITH clause with commas for multiple CTEs [OK]
      Common Mistakes:
      • Writing multiple WITH clauses in one query
      • Forgetting commas between CTEs
      • Assuming CTEs create permanent tables
      5. You want to calculate the average order amount per customer and then find customers whose average order is above 100. Which of the following queries correctly uses multiple CTEs to achieve this?
      hard
      A. WITH avg_orders AS (SELECT customer_id, AVG(amount) AS avg_amount FROM orders GROUP BY customer_id), high_avg AS (SELECT customer_id FROM avg_orders WHERE avg_amount > 100) SELECT * FROM high_avg;
      B. WITH avg_orders AS (SELECT customer_id, AVG(amount) AS avg_amount FROM orders), high_avg AS (SELECT customer_id FROM avg_orders WHERE avg_amount > 100) SELECT * FROM high_avg;
      C. WITH avg_orders AS (SELECT customer_id, amount FROM orders GROUP BY customer_id), high_avg AS (SELECT customer_id FROM avg_orders WHERE amount > 100) SELECT * FROM high_avg;
      D. WITH avg_orders AS (SELECT customer_id, AVG(amount) AS avg_amount FROM orders GROUP BY customer_id) SELECT * FROM avg_orders WHERE avg_amount > 100;

      Solution

      1. Step 1: Calculate average order per customer

        WITH avg_orders AS (SELECT customer_id, AVG(amount) AS avg_amount FROM orders GROUP BY customer_id), high_avg AS (SELECT customer_id FROM avg_orders WHERE avg_amount > 100) SELECT * FROM high_avg; correctly groups orders by customer_id and calculates AVG(amount).
      2. Step 2: Filter customers with avg_amount > 100

        WITH avg_orders AS (SELECT customer_id, AVG(amount) AS avg_amount FROM orders GROUP BY customer_id), high_avg AS (SELECT customer_id FROM avg_orders WHERE avg_amount > 100) SELECT * FROM high_avg; uses a second CTE to filter customers with average above 100, then selects from it.
      3. Final Answer:

        WITH avg_orders AS (SELECT customer_id, AVG(amount) AS avg_amount FROM orders GROUP BY customer_id), high_avg AS (SELECT customer_id FROM avg_orders WHERE avg_amount > 100) SELECT * FROM high_avg; -> Option A
      4. Quick Check:

        Multiple CTEs for calculation and filtering = C [OK]
      Hint: Use one CTE to calculate, second to filter results [OK]
      Common Mistakes:
      • Missing GROUP BY when calculating averages
      • Not filtering on aggregated column
      • Incorrect CTE definitions without commas
      Recommended

      Ready to prove it?

      Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

      10 questions~5 mineasy hard